[llvm] cb95690 - [InstCombine] fold mask with not-of-sext-bool to select

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 2 10:49:04 PST 2023


Author: Sanjay Patel
Date: 2023-01-02T13:33:28-05:00
New Revision: cb9569049c24e513afe215d5ac3b3dbc79dacf43

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

LOG: [InstCombine] fold mask with not-of-sext-bool to select

~sext(A) & Op1 --> A ? 0 : Op1

With no extra uses, this pattern is already reduced,
but we would miss it in examples such as issue #59773.

https://alive2.llvm.org/ce/z/WGLcSR

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/binop-cast.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index a4b14ad5eda1..48d57e39427d 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2360,6 +2360,16 @@ Instruction *InstCombinerImpl::visitAnd(BinaryOperator &I) {
       A->getType()->isIntOrIntVectorTy(1))
     return SelectInst::Create(A, Op0, Constant::getNullValue(Ty));
 
+  // Similarly, a 'not' of the bool translates to a swap of the select arms:
+  // ~sext(A) & Op1 --> A ? 0 : Op1
+  // Op0 & ~sext(A) --> A ? 0 : Op0
+  if (match(Op0, m_Not(m_SExt(m_Value(A)))) &&
+      A->getType()->isIntOrIntVectorTy(1))
+    return SelectInst::Create(A, Constant::getNullValue(Ty), Op1);
+  if (match(Op1, m_Not(m_SExt(m_Value(A)))) &&
+      A->getType()->isIntOrIntVectorTy(1))
+    return SelectInst::Create(A, Constant::getNullValue(Ty), Op0);
+
   // (iN X s>> (N-1)) & Y --> (X s< 0) ? Y : 0 -- with optional sext
   if (match(&I, m_c_And(m_OneUse(m_SExtOrSelf(
                             m_AShr(m_Value(X), m_APIntAllowUndef(C)))),

diff  --git a/llvm/test/Transforms/InstCombine/binop-cast.ll b/llvm/test/Transforms/InstCombine/binop-cast.ll
index e57f77ec06df..6bcd5049f92f 100644
--- a/llvm/test/Transforms/InstCombine/binop-cast.ll
+++ b/llvm/test/Transforms/InstCombine/binop-cast.ll
@@ -76,8 +76,7 @@ define <2 x i32> @and_not_sext_to_sel(<2 x i32> %x, <2 x i1> %y) {
 ; CHECK-LABEL: @and_not_sext_to_sel(
 ; CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i1> [[Y:%.*]] to <2 x i32>
 ; CHECK-NEXT:    call void @use_vec(<2 x i32> [[SEXT]])
-; CHECK-NEXT:    [[NOT:%.*]] = xor <2 x i32> [[SEXT]], <i32 -1, i32 -1>
-; CHECK-NEXT:    [[R:%.*]] = and <2 x i32> [[NOT]], [[X:%.*]]
+; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[Y]], <2 x i32> zeroinitializer, <2 x i32> [[X:%.*]]
 ; CHECK-NEXT:    ret <2 x i32> [[R]]
 ;
   %sext = sext <2 x i1> %y to <2 x i32>
@@ -94,7 +93,7 @@ define i32 @and_not_sext_to_sel_commute(i32 %px, i1 %y) {
 ; CHECK-NEXT:    call void @use(i32 [[SEXT]])
 ; CHECK-NEXT:    [[NOT:%.*]] = xor i32 [[SEXT]], -1
 ; CHECK-NEXT:    call void @use(i32 [[NOT]])
-; CHECK-NEXT:    [[R:%.*]] = and i32 [[X]], [[NOT]]
+; CHECK-NEXT:    [[R:%.*]] = select i1 [[Y]], i32 0, i32 [[X]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %x = mul i32 %px, %px ; thwart complexity-based canonicalization
@@ -106,6 +105,8 @@ define i32 @and_not_sext_to_sel_commute(i32 %px, i1 %y) {
   ret i32 %r
 }
 
+; negative test - must be 'not'
+
 define i32 @and_xor_sext_to_sel(i32 %x, i1 %y) {
 ; CHECK-LABEL: @and_xor_sext_to_sel(
 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[Y:%.*]] to i32
@@ -121,6 +122,8 @@ define i32 @and_xor_sext_to_sel(i32 %x, i1 %y) {
   ret i32 %r
 }
 
+; negative test - must be 'sext'
+
 define i32 @and_not_zext_to_sel(i32 %x, i1 %y) {
 ; CHECK-LABEL: @and_not_zext_to_sel(
 ; CHECK-NEXT:    [[ZEXT:%.*]] = zext i1 [[Y:%.*]] to i32


        


More information about the llvm-commits mailing list