[llvm] 430ad96 - [InstCombine] enhance bitwise select matching

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 23 07:05:04 PST 2021


Author: Sanjay Patel
Date: 2021-11-23T09:57:44-05:00
New Revision: 430ad9697d143b4c408acf0d0d01c17830ac2bb3

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

LOG: [InstCombine] enhance bitwise select matching

I noticed that adding a seemingly unrelated fold for xor caused
regressions on similar patterns, and this is one of the
underlying causes.

This could also be a variation for code as seen in:
https://llvm.org/PR34047
...although that exact example should be fixed after:
D113035 / c36b7e21bd8f

The vector test shows that we are actually missing a potential
canonicalization for bitcast-of-sext-of-not or the inverse.
The scalar test shows that even if we had that canonicalization,
it would still be possible to see this pattern due to extra uses.

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

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
    llvm/test/Transforms/InstCombine/logical-select.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 1e09766831613..5af453c972596 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -2353,11 +2353,20 @@ Value *InstCombinerImpl::getSelectCondition(Value *A, Value *B) {
   Value *Cond;
   Value *NotB;
   if (match(A, m_SExt(m_Value(Cond))) &&
-      Cond->getType()->isIntOrIntVectorTy(1) &&
-      match(B, m_OneUse(m_Not(m_Value(NotB))))) {
-    NotB = peekThroughBitcast(NotB, true);
-    if (match(NotB, m_SExt(m_Specific(Cond))))
+      Cond->getType()->isIntOrIntVectorTy(1)) {
+    // A = sext i1 Cond; B = sext (not (i1 Cond))
+    if (match(B, m_SExt(m_Not(m_Specific(Cond)))))
       return Cond;
+
+    // A = sext i1 Cond; B = not ({bitcast} (sext (i1 Cond)))
+    // TODO: The one-use checks are unnecessary or misplaced. If the caller
+    //       checked for uses on logic ops/casts, that should be enough to
+    //       make this transform worthwhile.
+    if (match(B, m_OneUse(m_Not(m_Value(NotB))))) {
+      NotB = peekThroughBitcast(NotB, true);
+      if (match(NotB, m_SExt(m_Specific(Cond))))
+        return Cond;
+    }
   }
 
   // All scalar (and most vector) possibilities should be handled now.

diff  --git a/llvm/test/Transforms/InstCombine/logical-select.ll b/llvm/test/Transforms/InstCombine/logical-select.ll
index 459e1b155453e..5093f20cba0c4 100644
--- a/llvm/test/Transforms/InstCombine/logical-select.ll
+++ b/llvm/test/Transforms/InstCombine/logical-select.ll
@@ -829,20 +829,15 @@ define i64 @bitcast_int_scalar_cond(<2 x i1> %b, i64 %c, i64 %d) {
   ret i64 %r
 }
 
-; TODO:
 ; Peek through bitcasts and sexts to find negated bool condition.
 
 define <1 x i6> @bitcast_sext_cond(<2 x i1> %cmp, <1 x i6> %a, <1 x i6> %b) {
 ; CHECK-LABEL: @bitcast_sext_cond(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <2 x i1> [[CMP:%.*]] to <2 x i3>
-; CHECK-NEXT:    [[BC1:%.*]] = bitcast <2 x i3> [[SEXT]] to <1 x i6>
-; CHECK-NEXT:    [[NEG:%.*]] = xor <2 x i1> [[CMP]], <i1 true, i1 true>
-; CHECK-NEXT:    [[SEXT2:%.*]] = sext <2 x i1> [[NEG]] to <2 x i3>
-; CHECK-NEXT:    [[BC2:%.*]] = bitcast <2 x i3> [[SEXT2]] to <1 x i6>
-; CHECK-NEXT:    [[AND1:%.*]] = and <1 x i6> [[BC1]], [[A:%.*]]
-; CHECK-NEXT:    [[AND2:%.*]] = and <1 x i6> [[BC2]], [[B:%.*]]
-; CHECK-NEXT:    [[OR:%.*]] = or <1 x i6> [[AND1]], [[AND2]]
-; CHECK-NEXT:    ret <1 x i6> [[OR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = bitcast <1 x i6> [[A:%.*]] to <2 x i3>
+; CHECK-NEXT:    [[TMP2:%.*]] = bitcast <1 x i6> [[B:%.*]] to <2 x i3>
+; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[CMP:%.*]], <2 x i3> [[TMP1]], <2 x i3> [[TMP2]]
+; CHECK-NEXT:    [[TMP4:%.*]] = bitcast <2 x i3> [[TMP3]] to <1 x i6>
+; CHECK-NEXT:    ret <1 x i6> [[TMP4]]
 ;
   %sext = sext <2 x i1> %cmp to <2 x i3>
   %bc1 = bitcast <2 x i3> %sext to <1 x i6>
@@ -855,7 +850,6 @@ define <1 x i6> @bitcast_sext_cond(<2 x i1> %cmp, <1 x i6> %a, <1 x i6> %b) {
   ret <1 x i6> %or
 }
 
-; TODO:
 ; Extra uses may prevent other transforms from creating the canonical patterns.
 
 define i8 @sext_cond_extra_uses(i1 %cmp, i8 %a, i8 %b) {
@@ -865,10 +859,8 @@ define i8 @sext_cond_extra_uses(i1 %cmp, i8 %a, i8 %b) {
 ; CHECK-NEXT:    call void @use(i8 [[SEXT1]])
 ; CHECK-NEXT:    [[SEXT2:%.*]] = sext i1 [[NEG]] to i8
 ; CHECK-NEXT:    call void @use(i8 [[SEXT2]])
-; CHECK-NEXT:    [[AND1:%.*]] = and i8 [[SEXT1]], [[A:%.*]]
-; CHECK-NEXT:    [[AND2:%.*]] = and i8 [[SEXT2]], [[B:%.*]]
-; CHECK-NEXT:    [[OR:%.*]] = or i8 [[AND1]], [[AND2]]
-; CHECK-NEXT:    ret i8 [[OR]]
+; CHECK-NEXT:    [[TMP1:%.*]] = select i1 [[CMP]], i8 [[A:%.*]], i8 [[B:%.*]]
+; CHECK-NEXT:    ret i8 [[TMP1]]
 ;
   %neg = xor i1 %cmp, -1
   %sext1 = sext i1 %cmp to i8


        


More information about the llvm-commits mailing list