[llvm] 0bb7be5 - [InstCombine] canonicalize 'not' ahead of bitcast+sext

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 24 12:48:18 PST 2023


Author: Sanjay Patel
Date: 2023-01-24T15:46:46-05:00
New Revision: 0bb7be5ff61e910addc5d8a7887f54d78a2d43ae

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

LOG: [InstCombine] canonicalize 'not' ahead of bitcast+sext

not (bitcast (sext i1 X)) --> bitcast (sext (not i1 X))

https://alive2.llvm.org/ce/z/-6Ygkd

This shows up as a potential regression if we change
canonicalization of ashr+not to icmp+sext.

Added: 
    

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

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
index 11a658f335e82..fc223835e3db1 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp
@@ -3949,6 +3949,15 @@ Instruction *InstCombinerImpl::foldNot(BinaryOperator &I) {
     return &I;
   }
 
+  // Move a 'not' ahead of casts of a bool to enable logic reduction:
+  // not (bitcast (sext i1 X)) --> bitcast (sext (not i1 X))
+  if (match(NotOp, m_OneUse(m_BitCast(m_OneUse(m_SExt(m_Value(X)))))) && X->getType()->isIntOrIntVectorTy(1)) {
+    Type *SextTy = cast<BitCastOperator>(NotOp)->getSrcTy();
+    Value *NotX = Builder.CreateNot(X);
+    Value *Sext = Builder.CreateSExt(NotX, SextTy);
+    return CastInst::CreateBitOrPointerCast(Sext, Ty);
+  }
+
   if (auto *NotOpI = dyn_cast<Instruction>(NotOp))
     if (sinkNotIntoLogicalOp(*NotOpI))
       return &I;

diff  --git a/llvm/test/Transforms/InstCombine/not.ll b/llvm/test/Transforms/InstCombine/not.ll
index 009649e226ec8..4bcde2c703c21 100644
--- a/llvm/test/Transforms/InstCombine/not.ll
+++ b/llvm/test/Transforms/InstCombine/not.ll
@@ -635,11 +635,13 @@ define i1 @not_logicalOr_not_op0_use2(i1 %x, i1 %y) {
   ret i1 %notor
 }
 
+; canonicalize 'not' ahead of casts of a bool value
+
 define <2 x i64> @bitcast_to_wide_elts_sext_bool(<4 x i1> %b) {
 ; CHECK-LABEL: @bitcast_to_wide_elts_sext_bool(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[B:%.*]] to <4 x i32>
-; CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i32> [[SEXT]] to <2 x i64>
-; CHECK-NEXT:    [[NOT:%.*]] = xor <2 x i64> [[BC]], <i64 -1, i64 -1>
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> [[B:%.*]], <i1 true, i1 true, i1 true, i1 true>
+; CHECK-NEXT:    [[TMP2:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32>
+; CHECK-NEXT:    [[NOT:%.*]] = bitcast <4 x i32> [[TMP2]] to <2 x i64>
 ; CHECK-NEXT:    ret <2 x i64> [[NOT]]
 ;
   %sext = sext <4 x i1> %b to <4 x i32>
@@ -650,9 +652,9 @@ define <2 x i64> @bitcast_to_wide_elts_sext_bool(<4 x i1> %b) {
 
 define <8 x i16> @bitcast_to_narrow_elts_sext_bool(<4 x i1> %b) {
 ; CHECK-LABEL: @bitcast_to_narrow_elts_sext_bool(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[B:%.*]] to <4 x i32>
-; CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i32> [[SEXT]] to <8 x i16>
-; CHECK-NEXT:    [[NOT:%.*]] = xor <8 x i16> [[BC]], <i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1>
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> [[B:%.*]], <i1 true, i1 true, i1 true, i1 true>
+; CHECK-NEXT:    [[TMP2:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32>
+; CHECK-NEXT:    [[NOT:%.*]] = bitcast <4 x i32> [[TMP2]] to <8 x i16>
 ; CHECK-NEXT:    ret <8 x i16> [[NOT]]
 ;
   %sext = sext <4 x i1> %b to <4 x i32>
@@ -663,9 +665,9 @@ define <8 x i16> @bitcast_to_narrow_elts_sext_bool(<4 x i1> %b) {
 
 define <2 x i16> @bitcast_to_vec_sext_bool(i1 %b) {
 ; CHECK-LABEL: @bitcast_to_vec_sext_bool(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[B:%.*]] to i32
-; CHECK-NEXT:    [[BC:%.*]] = bitcast i32 [[SEXT]] to <2 x i16>
-; CHECK-NEXT:    [[NOT:%.*]] = xor <2 x i16> [[BC]], <i16 -1, i16 -1>
+; CHECK-NEXT:    [[TMP1:%.*]] = xor i1 [[B:%.*]], true
+; CHECK-NEXT:    [[TMP2:%.*]] = sext i1 [[TMP1]] to i32
+; CHECK-NEXT:    [[NOT:%.*]] = bitcast i32 [[TMP2]] to <2 x i16>
 ; CHECK-NEXT:    ret <2 x i16> [[NOT]]
 ;
   %sext = sext i1 %b to i32
@@ -676,9 +678,9 @@ define <2 x i16> @bitcast_to_vec_sext_bool(i1 %b) {
 
 define i128 @bitcast_to_scalar_sext_bool(<4 x i1> %b) {
 ; CHECK-LABEL: @bitcast_to_scalar_sext_bool(
-; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[B:%.*]] to <4 x i32>
-; CHECK-NEXT:    [[BC:%.*]] = bitcast <4 x i32> [[SEXT]] to i128
-; CHECK-NEXT:    [[NOT:%.*]] = xor i128 [[BC]], -1
+; CHECK-NEXT:    [[TMP1:%.*]] = xor <4 x i1> [[B:%.*]], <i1 true, i1 true, i1 true, i1 true>
+; CHECK-NEXT:    [[TMP2:%.*]] = sext <4 x i1> [[TMP1]] to <4 x i32>
+; CHECK-NEXT:    [[NOT:%.*]] = bitcast <4 x i32> [[TMP2]] to i128
 ; CHECK-NEXT:    ret i128 [[NOT]]
 ;
   %sext = sext <4 x i1> %b to <4 x i32>
@@ -687,6 +689,8 @@ define i128 @bitcast_to_scalar_sext_bool(<4 x i1> %b) {
   ret i128 %not
 }
 
+; negative test
+
 define <2 x i4> @bitcast_to_vec_sext_bool_use1(i1 %b) {
 ; CHECK-LABEL: @bitcast_to_vec_sext_bool_use1(
 ; CHECK-NEXT:    [[SEXT:%.*]] = sext i1 [[B:%.*]] to i8
@@ -702,6 +706,8 @@ define <2 x i4> @bitcast_to_vec_sext_bool_use1(i1 %b) {
   ret <2 x i4> %not
 }
 
+; negative test
+
 define i8 @bitcast_to_scalar_sext_bool_use2(<4 x i1> %b) {
 ; CHECK-LABEL: @bitcast_to_scalar_sext_bool_use2(
 ; CHECK-NEXT:    [[SEXT:%.*]] = sext <4 x i1> [[B:%.*]] to <4 x i2>


        


More information about the llvm-commits mailing list