[llvm] f9f40aa - [InstCombine] fold negated low-bit-mask to cmp+select

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sun Jul 3 09:27:05 PDT 2022


Author: Sanjay Patel
Date: 2022-07-03T12:25:26-04:00
New Revision: f9f40aa10d9862b8db1b99bb9e7f5898a90b35f7

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

LOG: [InstCombine] fold negated low-bit-mask to cmp+select

(-(X & 1)) & Y --> (X & 1) == 0 ? 0 : Y
https://alive2.llvm.org/ce/z/rhpH3i

This is noted as a missing IR canonicalization in issue #55618.
We already managed to fix codegen to the expected form.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/and.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index ae8865651ece..d3578fe4a2ba 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -1771,6 +1771,16 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
     return new ZExtInst(IsZero, Ty);
   }
 
+  // (-(X & 1)) & Y --> (X & 1) == 0 ? 0 : Y
+  Value *Neg;
+  if (match(&I,
+            m_c_And(m_CombineAnd(m_Value(Neg),
+                                 m_OneUse(m_Neg(m_And(m_Value(), m_One())))),
+                    m_Value(Y)))) {
+    Value *Cmp = Builder.CreateIsNull(Neg);
+    return SelectInst::Create(Cmp, ConstantInt::getNullValue(Ty), Y);
+  }
+
   const APInt *C;
   if (match(Op1, m_APInt(C))) {
     const APInt *XorC;

diff  --git a/llvm/test/Transforms/InstCombine/and.ll b/llvm/test/Transforms/InstCombine/and.ll
index 9cf9c720473c..e37a34859dca 100644
--- a/llvm/test/Transforms/InstCombine/and.ll
+++ b/llvm/test/Transforms/InstCombine/and.ll
@@ -2171,8 +2171,8 @@ define <3 x i16> @lshr_shl_pow2_const_case1_undef3_vec(<3 x i16> %x) {
 define i8 @negate_lowbitmask(i8 %x, i8 %y) {
 ; CHECK-LABEL: @negate_lowbitmask(
 ; CHECK-NEXT:    [[A:%.*]] = and i8 [[X:%.*]], 1
-; CHECK-NEXT:    [[N:%.*]] = sub nsw i8 0, [[A]]
-; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[A]], 0
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i8 0, i8 [[Y:%.*]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %a = and i8 %x, 1
@@ -2185,8 +2185,8 @@ define <2 x i5> @negate_lowbitmask_commute(<2 x i5> %x, <2 x i5> %p) {
 ; CHECK-LABEL: @negate_lowbitmask_commute(
 ; CHECK-NEXT:    [[Y:%.*]] = mul <2 x i5> [[P:%.*]], [[P]]
 ; CHECK-NEXT:    [[A:%.*]] = and <2 x i5> [[X:%.*]], <i5 1, i5 poison>
-; CHECK-NEXT:    [[N:%.*]] = sub <2 x i5> <i5 poison, i5 0>, [[A]]
-; CHECK-NEXT:    [[R:%.*]] = and <2 x i5> [[Y]], [[N]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq <2 x i5> [[A]], <i5 poison, i5 0>
+; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP1]], <2 x i5> zeroinitializer, <2 x i5> [[Y]]
 ; CHECK-NEXT:    ret <2 x i5> [[R]]
 ;
   %y = mul <2 x i5> %p, %p ; thwart complexity-based canonicalization
@@ -2200,8 +2200,8 @@ define i8 @negate_lowbitmask_use1(i8 %x, i8 %y) {
 ; CHECK-LABEL: @negate_lowbitmask_use1(
 ; CHECK-NEXT:    [[A:%.*]] = and i8 [[X:%.*]], 1
 ; CHECK-NEXT:    call void @use8(i8 [[A]])
-; CHECK-NEXT:    [[N:%.*]] = sub nsw i8 0, [[A]]
-; CHECK-NEXT:    [[R:%.*]] = and i8 [[N]], [[Y:%.*]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i8 [[A]], 0
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[TMP1]], i8 0, i8 [[Y:%.*]]
 ; CHECK-NEXT:    ret i8 [[R]]
 ;
   %a = and i8 %x, 1
@@ -2211,6 +2211,8 @@ define i8 @negate_lowbitmask_use1(i8 %x, i8 %y) {
   ret i8 %r
 }
 
+; negative test
+
 define i8 @negate_lowbitmask_use2(i8 %x, i8 %y) {
 ; CHECK-LABEL: @negate_lowbitmask_use2(
 ; CHECK-NEXT:    [[A:%.*]] = and i8 [[X:%.*]], 1


        


More information about the llvm-commits mailing list