[InstCombine] fix overzealous assert in icmp-shr fold
authorSanjay Patel <spatel@rotateright.com>
Thu, 30 Jun 2022 10:14:30 +0000 (06:14 -0400)
committerSanjay Patel <spatel@rotateright.com>
Thu, 30 Jun 2022 10:28:48 +0000 (06:28 -0400)
The assert was added with 0399473de886595d and is correct for that
pattern, but it is off-by-1 with the enhancement in d4f39d833332.

The transforms are still correct with the new pre-condition:
https://alive2.llvm.org/ce/z/6_6ghm
https://alive2.llvm.org/ce/z/_GTBUt

And as shown in the new test, the transform is expected with
'ult' - in that case, the icmp reduces to test if the shift
amount is 0.

llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
llvm/test/Transforms/InstCombine/icmp-shr.ll

index 4f1ca45..ebe1676 100644 (file)
@@ -2230,7 +2230,7 @@ Instruction *InstCombinerImpl::foldICmpShrConstant(ICmpInst &Cmp,
     if (!IsAShr && ShiftValC->isPowerOf2() &&
         (Pred == CmpInst::ICMP_UGT || Pred == CmpInst::ICMP_ULT)) {
       bool IsUGT = Pred == CmpInst::ICMP_UGT;
-      assert(ShiftValC->ugt(C) && "Expected simplify of compare");
+      assert(ShiftValC->uge(C) && "Expected simplify of compare");
       assert(IsUGT || !C.isZero() && "Expected X u< 0 to simplify");
 
       unsigned CmpLZ =
index 5196eac..c910108 100644 (file)
@@ -1136,6 +1136,16 @@ define i1 @lshr_not_pow2_ult(i8 %x) {
   ret i1 %r
 }
 
+define i1 @lshr_pow2_ult_equal_constants(i32 %x) {
+; CHECK-LABEL: @lshr_pow2_ult_equal_constants(
+; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[X:%.*]], 0
+; CHECK-NEXT:    ret i1 [[R]]
+;
+  %shr = lshr i32 16, %x
+  %r = icmp ult i32 %shr, 16
+  ret i1 %r
+}
+
 ; TODO: This should reduce to X != 0.
 
 define i1 @lshr_pow2_ult_smin(i8 %x) {