[llvm] 1462bdf - [InstCombine] fold abs(srem X, 2)

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 31 08:50:27 PDT 2021


Author: Sanjay Patel
Date: 2021-03-31T11:29:20-04:00
New Revision: 1462bdf1b985256fb52ddccdbbe8fbf5a9ad48b5

URL: https://github.com/llvm/llvm-project/commit/1462bdf1b985256fb52ddccdbbe8fbf5a9ad48b5
DIFF: https://github.com/llvm/llvm-project/commit/1462bdf1b985256fb52ddccdbbe8fbf5a9ad48b5.diff

LOG: [InstCombine] fold abs(srem X, 2)

This is a missing optimization based on an example in:
https://llvm.org/PR49763

As noted there and the test here, we could add a more
general fold if that is shown useful.

https://alive2.llvm.org/ce/z/xEHdTv
https://alive2.llvm.org/ce/z/97dcY5

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/test/Transforms/InstCombine/abs-intrinsic.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index 837740276972a..bf1c51e6f6c2d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -839,6 +839,12 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
       return CastInst::Create(Instruction::ZExt, NarrowAbs, II->getType());
     }
 
+    // Match a complicated way to check if a number is odd/even:
+    // abs (srem X, 2) --> and X, 1
+    const APInt *C;
+    if (match(IIOperand, m_SRem(m_Value(X), m_APInt(C))) && *C == 2)
+      return BinaryOperator::CreateAnd(X, ConstantInt::get(II->getType(), 1));
+
     break;
   }
   case Intrinsic::umax:

diff  --git a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
index db702486c8dd5..56ba17fe07385 100644
--- a/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
+++ b/llvm/test/Transforms/InstCombine/abs-intrinsic.ll
@@ -391,8 +391,7 @@ define i32 @demand_low_bits(i32 %x) {
 
 define i32 @srem_by_2_int_min_is_poison(i32 %x) {
 ; CHECK-LABEL: @srem_by_2_int_min_is_poison(
-; CHECK-NEXT:    [[S:%.*]] = srem i32 [[X:%.*]], 2
-; CHECK-NEXT:    [[R:%.*]] = call i32 @llvm.abs.i32(i32 [[S]], i1 true)
+; CHECK-NEXT:    [[R:%.*]] = and i32 [[X:%.*]], 1
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %s = srem i32 %x, 2
@@ -404,7 +403,7 @@ define <3 x i82> @srem_by_2(<3 x i82> %x, <3 x i82>* %p) {
 ; CHECK-LABEL: @srem_by_2(
 ; CHECK-NEXT:    [[S:%.*]] = srem <3 x i82> [[X:%.*]], <i82 2, i82 2, i82 2>
 ; CHECK-NEXT:    store <3 x i82> [[S]], <3 x i82>* [[P:%.*]], align 64
-; CHECK-NEXT:    [[R:%.*]] = call <3 x i82> @llvm.abs.v3i82(<3 x i82> [[S]], i1 false)
+; CHECK-NEXT:    [[R:%.*]] = and <3 x i82> [[X]], <i82 1, i82 1, i82 1>
 ; CHECK-NEXT:    ret <3 x i82> [[R]]
 ;
   %s = srem <3 x i82> %x, <i82 2, i82 2, i82 2>
@@ -413,6 +412,8 @@ define <3 x i82> @srem_by_2(<3 x i82> %x, <3 x i82>* %p) {
   ret <3 x i82> %r
 }
 
+; TODO: A more general transform could sink the srem and turn it into urem.
+
 define i32 @srem_by_3(i32 %x) {
 ; CHECK-LABEL: @srem_by_3(
 ; CHECK-NEXT:    [[S:%.*]] = srem i32 [[X:%.*]], 3


        


More information about the llvm-commits mailing list