[llvm] 9b76168 - [ValueTracking] Fix i1 abs range (PR62760)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Wed May 17 03:31:24 PDT 2023


Author: Nikita Popov
Date: 2023-05-17T12:31:13+02:00
New Revision: 9b7616856cbdd476aaf4553ccc74ab8c38c5f6ad

URL: https://github.com/llvm/llvm-project/commit/9b7616856cbdd476aaf4553ccc74ab8c38c5f6ad
DIFF: https://github.com/llvm/llvm-project/commit/9b7616856cbdd476aaf4553ccc74ab8c38c5f6ad.diff

LOG: [ValueTracking] Fix i1 abs range (PR62760)

For i1 operations, we may end up returning an empty range instead
of a full one. Make sure to use the getNonEmpty constructor.

Fixes https://github.com/llvm/llvm-project/issues/62760.

Added: 
    

Modified: 
    llvm/lib/Analysis/ValueTracking.cpp
    llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
    llvm/test/Transforms/InstSimplify/call.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 0368c090665f..6f602da569e8 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -8701,7 +8701,8 @@ static ConstantRange getRangeForIntrinsic(const IntrinsicInst &II) {
   case Intrinsic::ctlz:
   case Intrinsic::cttz:
     // Maximum of set/clear bits is the bit width.
-    return ConstantRange(APInt::getZero(Width), APInt(Width, Width + 1));
+    return ConstantRange::getNonEmpty(APInt::getZero(Width),
+                                      APInt(Width, Width + 1));
   case Intrinsic::uadd_sat:
     // uadd.sat(x, C) produces [C, UINT_MAX].
     if (match(II.getOperand(0), m_APInt(C)) ||
@@ -8782,11 +8783,11 @@ static ConstantRange getRangeForIntrinsic(const IntrinsicInst &II) {
     // If abs of SIGNED_MIN is poison, then the result is [0..SIGNED_MAX],
     // otherwise it is [0..SIGNED_MIN], as -SIGNED_MIN == SIGNED_MIN.
     if (match(II.getOperand(1), m_One()))
-      return ConstantRange(APInt::getZero(Width),
-                           APInt::getSignedMaxValue(Width) + 1);
+      return ConstantRange::getNonEmpty(APInt::getZero(Width),
+                                        APInt::getSignedMaxValue(Width) + 1);
 
-    return ConstantRange(APInt::getZero(Width),
-                         APInt::getSignedMinValue(Width) + 1);
+    return ConstantRange::getNonEmpty(APInt::getZero(Width),
+                                      APInt::getSignedMinValue(Width) + 1);
   case Intrinsic::vscale:
     if (!II.getParent() || !II.getFunction())
       break;

diff  --git a/llvm/test/Transforms/InstSimplify/abs_intrinsic.ll b/llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
index ca1ee9461cf7..4153872c0adc 100644
--- a/llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
+++ b/llvm/test/Transforms/InstSimplify/abs_intrinsic.ll
@@ -292,10 +292,11 @@ define i32 @select_nabs_of_abs_ne(i32 %x) {
   ret i32 %sel
 }
 
-; FIXME: This is a miscompile.
 define i1 @abs_i1_non_poison_eq_false(i1 %x) {
 ; CHECK-LABEL: @abs_i1_non_poison_eq_false(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[ABS:%.*]] = call i1 @llvm.abs.i1(i1 [[X:%.*]], i1 false)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i1 [[ABS]], false
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %abs = call i1 @llvm.abs.i1(i1 %x, i1 false)
   %cmp = icmp eq i1 %abs, false

diff  --git a/llvm/test/Transforms/InstSimplify/call.ll b/llvm/test/Transforms/InstSimplify/call.ll
index 449a60e79f3e..52c207a27604 100644
--- a/llvm/test/Transforms/InstSimplify/call.ll
+++ b/llvm/test/Transforms/InstSimplify/call.ll
@@ -1569,10 +1569,11 @@ define i1 @capture_vs_recurse(i64 %mask) {
   ret i1 %cmp
 }
 
-; FIXME: This is a miscompile.
 define i1 @ctlz_i1_non_poison_eq_false(i1 %x) {
 ; CHECK-LABEL: @ctlz_i1_non_poison_eq_false(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CT:%.*]] = call i1 @llvm.ctlz.i1(i1 [[X:%.*]], i1 false)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i1 [[CT]], false
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %ct = call i1 @llvm.ctlz.i1(i1 %x, i1 false)
   %cmp = icmp eq i1 %ct, false
@@ -1581,17 +1582,20 @@ define i1 @ctlz_i1_non_poison_eq_false(i1 %x) {
 
 define i1 @ctlz_i1_poison_eq_false(i1 %x) {
 ; CHECK-LABEL: @ctlz_i1_poison_eq_false(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CT:%.*]] = call i1 @llvm.ctlz.i1(i1 [[X:%.*]], i1 true)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i1 [[CT]], false
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %ct = call i1 @llvm.ctlz.i1(i1 %x, i1 true)
   %cmp = icmp eq i1 %ct, false
   ret i1 %cmp
 }
 
-; FIXME: This is a miscompile.
 define i1 @cttz_i1_non_poison_eq_false(i1 %x) {
 ; CHECK-LABEL: @cttz_i1_non_poison_eq_false(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CT:%.*]] = call i1 @llvm.cttz.i1(i1 [[X:%.*]], i1 false)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i1 [[CT]], false
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %ct = call i1 @llvm.cttz.i1(i1 %x, i1 false)
   %cmp = icmp eq i1 %ct, false
@@ -1600,7 +1604,9 @@ define i1 @cttz_i1_non_poison_eq_false(i1 %x) {
 
 define i1 @cttz_i1_poison_eq_false(i1 %x) {
 ; CHECK-LABEL: @cttz_i1_poison_eq_false(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    [[CT:%.*]] = call i1 @llvm.cttz.i1(i1 [[X:%.*]], i1 true)
+; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i1 [[CT]], false
+; CHECK-NEXT:    ret i1 [[CMP]]
 ;
   %ct = call i1 @llvm.cttz.i1(i1 %x, i1 true)
   %cmp = icmp eq i1 %ct, false


        


More information about the llvm-commits mailing list