Skip to content

Commit

Permalink
[InstCombine] Prevent infinite loop with two shifts
Browse files Browse the repository at this point in the history
The following pattern: `(C2 << X) << C1` will usually be
transformed into `(C2 << C1) << X`, essentially swapping `X` and `C1`.

However, this should not be done when `X` is also a constant, as this
can lead to swapping both constants indefinitely.

This fixes llvm#118798
  • Loading branch information
momo5502 committed Dec 5, 2024
1 parent ff78cd5 commit 5977d79
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 1 deletion.
4 changes: 3 additions & 1 deletion llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,9 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *C1,
Constant *C2;
Value *X;
bool IsLeftShift = I.getOpcode() == Instruction::Shl;
if (match(Op0, m_BinOp(I.getOpcode(), m_ImmConstant(C2), m_Value(X)))) {
if (match(Op0,
m_BinOp(I.getOpcode(), m_ImmConstant(C2),
m_CombineAnd(m_Value(X), m_Unless(m_Constant()))))) {
Instruction *R = BinaryOperator::Create(
I.getOpcode(), Builder.CreateBinOp(I.getOpcode(), C2, C1), X);
BinaryOperator *BO0 = cast<BinaryOperator>(Op0);
Expand Down
22 changes: 22 additions & 0 deletions llvm/test/Transforms/InstCombine/shl-twice-constant.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
; RUN: opt < %s -passes=instcombine -S | FileCheck %s

@c = external constant i8
@c2 = external constant i8

define i16 @testfunc() {
; CHECK-LABEL: @testfunc(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i64 1, ptrtoint (ptr @c2 to i64)
; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], ptrtoint (ptr @c to i64)
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr
; CHECK-NEXT: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 1
; CHECK-NEXT: ret i16 [[TMP3]]
;
entry:
%0 = shl i64 1, ptrtoint (ptr @c2 to i64)
%1 = shl i64 %0, ptrtoint (ptr @c to i64)
%2 = inttoptr i64 %1 to ptr
%3 = load i16, ptr %2, align 1
ret i16 %3
}

0 comments on commit 5977d79

Please sign in to comment.