Author: Sanjay Patel Date: 2020-07-16T17:06:22+02:00 New Revision: 12aa43e621ff3b60b515eaf33bb25ba439094140
URL: https://github.com/llvm/llvm-project/commit/12aa43e621ff3b60b515eaf33bb25ba439094140 DIFF: https://github.com/llvm/llvm-project/commit/12aa43e621ff3b60b515eaf33bb25ba439094140.diff LOG: [InstCombine] prevent infinite looping in or-icmp fold (PR46712) I'm not sure if the test is truly minimal, but we need to induce a situation where a value becomes a constant but is not immediately folded before getting to the 'or' transform. (cherry picked from commit d8b268680d0858aaf30cb1a278b64b11361bc780) Added: Modified: llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp llvm/test/Transforms/InstCombine/or.ll Removed: ################################################################################ diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp index d3c718a919c0..1304d46fdef4 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -1148,11 +1148,12 @@ static Value *foldAndOrOfICmpsWithConstEq(ICmpInst *Cmp0, ICmpInst *Cmp1, assert((IsAnd || Logic.getOpcode() == Instruction::Or) && "Wrong logic op"); // Match an equality compare with a non-poison constant as Cmp0. + // Also, give up if the compare can be constant-folded to avoid looping. ICmpInst::Predicate Pred0; Value *X; Constant *C; if (!match(Cmp0, m_ICmp(Pred0, m_Value(X), m_Constant(C))) || - !isGuaranteedNotToBeUndefOrPoison(C)) + !isGuaranteedNotToBeUndefOrPoison(C) || isa<Constant>(X)) return nullptr; if ((IsAnd && Pred0 != ICmpInst::ICMP_EQ) || (!IsAnd && Pred0 != ICmpInst::ICMP_NE)) diff --git a/llvm/test/Transforms/InstCombine/or.ll b/llvm/test/Transforms/InstCombine/or.ll index b747c5d97810..48496948c190 100644 --- a/llvm/test/Transforms/InstCombine/or.ll +++ b/llvm/test/Transforms/InstCombine/or.ll @@ -841,3 +841,38 @@ define <16 x i1> @test51(<16 x i1> %arg, <16 x i1> %arg1) { %tmp3 = or <16 x i1> %tmp, %tmp2 ret <16 x i1> %tmp3 } + +; This would infinite loop because it reaches a transform +; that was not expecting a constant-foldable value. + +define i32 @PR46712(i1 %x, i1 %y, i1 %b, i64 %z) { +; CHECK-LABEL: @PR46712( +; CHECK-NEXT: entry: +; CHECK-NEXT: br i1 [[B:%.*]], label [[TRUE:%.*]], label [[END:%.*]] +; CHECK: true: +; CHECK-NEXT: [[BOOL5:%.*]] = icmp eq i64 [[Z:%.*]], 0 +; CHECK-NEXT: [[SEL:%.*]] = zext i1 [[BOOL5]] to i32 +; CHECK-NEXT: br label [[END]] +; CHECK: end: +; CHECK-NEXT: [[T5:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[SEL]], [[TRUE]] ] +; CHECK-NEXT: ret i32 [[T5]] +; +entry: + %t2 = or i1 %x, %y + %conv = sext i1 %t2 to i32 + %cmp = icmp sge i32 %conv, 1 + %conv2 = zext i1 %cmp to i64 + br i1 %b, label %true, label %end + +true: + %bool4 = icmp eq i64 %conv2, 0 + %bool5 = icmp ne i64 %z, 0 + %and = and i1 %bool4, %bool5 + %sel = select i1 %and, i1 false, i1 true + br label %end + +end: + %t5 = phi i1 [ 0, %entry ], [ %sel, %true ] + %conv8 = zext i1 %t5 to i32 + ret i32 %conv8 +} _______________________________________________ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits