[InstCombine] add fold for demand of low bit of abs()
authorSanjay Patel <spatel@rotateright.com>
Tue, 30 Mar 2021 18:33:30 +0000 (14:33 -0400)
committerSanjay Patel <spatel@rotateright.com>
Tue, 30 Mar 2021 19:14:37 +0000 (15:14 -0400)
This is one problem shown in https://llvm.org/PR49763

https://alive2.llvm.org/ce/z/cV6-4K
https://alive2.llvm.org/ce/z/9_3g-L

llvm/lib/Transforms/InstCombine/InstCombineSimplifyDemanded.cpp
llvm/test/Transforms/InstCombine/abs-intrinsic.ll

index 16efe86..54ca2c1 100644 (file)
@@ -734,6 +734,11 @@ Value *InstCombinerImpl::SimplifyDemandedUseBits(Value *V, APInt DemandedMask,
     bool KnownBitsComputed = false;
     if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
       switch (II->getIntrinsicID()) {
+      case Intrinsic::abs: {
+        if (DemandedMask == 1)
+          return II->getArgOperand(0);
+        break;
+      }
       case Intrinsic::bswap: {
         // If the only bits demanded come from one byte of the bswap result,
         // just shift the input byte into position to eliminate the bswap.
index a8ee1a9..9961c71 100644 (file)
@@ -352,10 +352,11 @@ define <4 x i8> @trunc_abs_sext_vec(<4 x i8> %x) {
   ret <4 x i8> %t
 }
 
+; abs() doesn't change the low bit.
+
 define i32 @demand_low_bit(i32 %x) {
 ; CHECK-LABEL: @demand_low_bit(
-; CHECK-NEXT:    [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)
-; CHECK-NEXT:    [[R:%.*]] = and i32 [[A]], 1
+; CHECK-NEXT:    [[R:%.*]] = and i32 [[X:%.*]], 1
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %a = call i32 @llvm.abs.i32(i32 %x, i1 false)
@@ -363,10 +364,11 @@ define i32 @demand_low_bit(i32 %x) {
   ret i32 %r
 }
 
+; Int min behavior doesn't affect the transform.
+
 define <3 x i82> @demand_low_bit_int_min_is_poison(<3 x i82> %x) {
 ; CHECK-LABEL: @demand_low_bit_int_min_is_poison(
-; CHECK-NEXT:    [[A:%.*]] = call <3 x i82> @llvm.abs.v3i82(<3 x i82> [[X:%.*]], i1 true)
-; CHECK-NEXT:    [[R:%.*]] = shl <3 x i82> [[A]], <i82 81, i82 81, i82 81>
+; CHECK-NEXT:    [[R:%.*]] = shl <3 x i82> [[X:%.*]], <i82 81, i82 81, i82 81>
 ; CHECK-NEXT:    ret <3 x i82> [[R]]
 ;
   %a = call <3 x i82> @llvm.abs.v3i82(<3 x i82> %x, i1 true)
@@ -374,6 +376,8 @@ define <3 x i82> @demand_low_bit_int_min_is_poison(<3 x i82> %x) {
   ret <3 x i82> %r
 }
 
+; Negative test - only low bit is allowed.
+
 define i32 @demand_low_bits(i32 %x) {
 ; CHECK-LABEL: @demand_low_bits(
 ; CHECK-NEXT:    [[A:%.*]] = call i32 @llvm.abs.i32(i32 [[X:%.*]], i1 false)