Skip to content

Commit 5977d79

Browse files
committed
[InstCombine] Prevent infinite loop with two shifts
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 #118798
1 parent ff78cd5 commit 5977d79

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,7 +786,9 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *C1,
786786
Constant *C2;
787787
Value *X;
788788
bool IsLeftShift = I.getOpcode() == Instruction::Shl;
789-
if (match(Op0, m_BinOp(I.getOpcode(), m_ImmConstant(C2), m_Value(X)))) {
789+
if (match(Op0,
790+
m_BinOp(I.getOpcode(), m_ImmConstant(C2),
791+
m_CombineAnd(m_Value(X), m_Unless(m_Constant()))))) {
790792
Instruction *R = BinaryOperator::Create(
791793
I.getOpcode(), Builder.CreateBinOp(I.getOpcode(), C2, C1), X);
792794
BinaryOperator *BO0 = cast<BinaryOperator>(Op0);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2+
; RUN: opt < %s -passes=instcombine -S | FileCheck %s
3+
4+
@c = external constant i8
5+
@c2 = external constant i8
6+
7+
define i16 @testfunc() {
8+
; CHECK-LABEL: @testfunc(
9+
; CHECK-NEXT: entry:
10+
; CHECK-NEXT: [[TMP0:%.*]] = shl nuw i64 1, ptrtoint (ptr @c2 to i64)
11+
; CHECK-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], ptrtoint (ptr @c to i64)
12+
; CHECK-NEXT: [[TMP2:%.*]] = inttoptr i64 [[TMP1]] to ptr
13+
; CHECK-NEXT: [[TMP3:%.*]] = load i16, ptr [[TMP2]], align 1
14+
; CHECK-NEXT: ret i16 [[TMP3]]
15+
;
16+
entry:
17+
%0 = shl i64 1, ptrtoint (ptr @c2 to i64)
18+
%1 = shl i64 %0, ptrtoint (ptr @c to i64)
19+
%2 = inttoptr i64 %1 to ptr
20+
%3 = load i16, ptr %2, align 1
21+
ret i16 %3
22+
}

0 commit comments

Comments
 (0)