Skip to content

Commit 0d83e72

Browse files
committed
[InstCombine] fix infinite loop from shift transform
I'm not sure if there is a better way or another bug still here, but this is enough to avoid the loop from: https://llvm.org/PR51657 The test requires multiple blocks and datalayout to trigger the problem path.
1 parent c85f450 commit 0d83e72

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

llvm/lib/Transforms/InstCombine/InstCombineShifts.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -696,13 +696,14 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
696696
// Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
697697
// If 'shift2' is an ashr, we would have to get the sign bit into a funny
698698
// place. Don't try to do this transformation in this case. Also, we
699-
// require that the input operand is a shift-by-constant so that we have
700-
// confidence that the shifts will get folded together. We could do this
699+
// require that the input operand is a non-poison shift-by-constant so that we
700+
// have confidence that the shifts will get folded together. We could do this
701701
// xform in more cases, but it is unlikely to be profitable.
702702
Instruction *TrOp;
703703
const APInt *TrShiftAmt;
704704
if (I.isLogicalShift() && match(Op0, m_Trunc(m_Instruction(TrOp))) &&
705-
match(TrOp, m_Shift(m_Value(), m_APInt(TrShiftAmt)))) {
705+
match(TrOp, m_Shift(m_Value(), m_APInt(TrShiftAmt))) &&
706+
TrShiftAmt->ult(TrOp->getType()->getScalarSizeInBits())) {
706707
Type *SrcTy = TrOp->getType();
707708

708709
// Okay, we'll do this xform. Make the shift of shift.

llvm/test/Transforms/InstCombine/shift-amount-reassociation-with-truncation-shl.ll

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
22
; RUN: opt < %s -instcombine -S | FileCheck %s
33

4+
target datalayout = "n8:16:32"
5+
46
; Given pattern:
57
; (trunc (x << Q) to iDst) << K
68
; we should rewrite it as
@@ -227,3 +229,34 @@ define i16 @shl_tr_shl_constant_shift_amount_uses(i32 %x) {
227229
%r = shl i16 %tr, 4
228230
ret i16 %r
229231
}
232+
233+
; This would infinite loop because we did not process the
234+
; poison shift before trying to fold shift-of-shift. To reach
235+
; the problematic transform, it needs a datalayout to specify
236+
; that the narrow types are legal, but i64 is not.
237+
238+
define i1 @PR51657(i64 %x) {
239+
; CHECK-LABEL: @PR51657(
240+
; CHECK-NEXT: entry:
241+
; CHECK-NEXT: br i1 undef, label [[COND_FALSE:%.*]], label [[COND_END:%.*]]
242+
; CHECK: cond.false:
243+
; CHECK-NEXT: br label [[COND_END]]
244+
; CHECK: cond.end:
245+
; CHECK-NEXT: ret i1 true
246+
;
247+
entry:
248+
br i1 undef, label %cond.false, label %cond.end
249+
250+
cond.false:
251+
%shl = shl i64 %x, 64
252+
%conv26 = trunc i64 %shl to i32
253+
%t1 = trunc i64 %shl to i8
254+
br label %cond.end
255+
256+
cond.end:
257+
%cond = phi i32 [ %conv26, %cond.false ], [ 0, %entry ]
258+
%t2 = phi i8 [ %t1, %cond.false ], [ 0, %entry ]
259+
%conv27 = sext i8 %t2 to i32
260+
%eq = icmp eq i32 %cond, %conv27
261+
ret i1 %eq
262+
}

0 commit comments

Comments
 (0)