[llvm] c6e5602 - [InstCombine] fold signbit splat pattern that uses negate

Sanjay Patel via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 27 05:38:46 PDT 2022


Author: Sanjay Patel
Date: 2022-08-27T08:04:35-04:00
New Revision: c6e56024c699cb60cd1e8ece66e866ae0b9a6c7b

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

LOG: [InstCombine] fold signbit splat pattern that uses negate

0 - (zext (i8 X u>> 7) to iN) --> sext (i8 X s>> 7) to iN

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

This is part of solving issue #57381.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
    llvm/test/Transforms/InstCombine/negated-bitmask.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
index a0a5926d2771e..cc6bbc357a278 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineNegator.cpp
@@ -248,6 +248,19 @@ std::array<Value *, 2> Negator::getSortedOperandsOfBinOp(Instruction *I) {
     return nullptr;
 
   switch (I->getOpcode()) {
+  case Instruction::ZExt: {
+    // Negation of zext of signbit is signbit splat:
+    // 0 - (zext (i8 X u>> 7) to iN) --> sext (i8 X s>> 7) to iN
+    Value *SrcOp = I->getOperand(0);
+    unsigned SrcWidth = SrcOp->getType()->getScalarSizeInBits();
+    const APInt &FullShift = APInt(SrcWidth, SrcWidth - 1);
+    if (IsTrulyNegation &&
+        match(SrcOp, m_LShr(m_Value(X), m_SpecificIntAllowUndef(FullShift)))) {
+      Value *Ashr = Builder.CreateAShr(X, FullShift);
+      return Builder.CreateSExt(Ashr, I->getType());
+    }
+    break;
+  }
   case Instruction::And: {
     Constant *ShAmt;
     // sub(y,and(lshr(x,C),1)) --> add(ashr(shl(x,(BW-1)-C),BW-1),y)

diff  --git a/llvm/test/Transforms/InstCombine/negated-bitmask.ll b/llvm/test/Transforms/InstCombine/negated-bitmask.ll
index ba53c2483acdf..12223c75996d5 100644
--- a/llvm/test/Transforms/InstCombine/negated-bitmask.ll
+++ b/llvm/test/Transforms/InstCombine/negated-bitmask.ll
@@ -186,10 +186,9 @@ define <2 x i32> @neg_mask1_lshr_extrause_lshr(<2 x i32> %a0) {
 
 define i32 @neg_signbit(i8 %x) {
 ; CHECK-LABEL: @neg_signbit(
-; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[X:%.*]], 7
-; CHECK-NEXT:    [[Z:%.*]] = zext i8 [[S]] to i32
-; CHECK-NEXT:    [[R:%.*]] = sub nsw i32 0, [[Z]]
-; CHECK-NEXT:    ret i32 [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i8 [[X:%.*]], 7
+; CHECK-NEXT:    [[TMP2:%.*]] = sext i8 [[TMP1]] to i32
+; CHECK-NEXT:    ret i32 [[TMP2]]
 ;
   %s = lshr i8 %x, 7
   %z = zext i8 %s to i32
@@ -201,9 +200,9 @@ define <2 x i64> @neg_signbit_use1(<2 x i32> %x) {
 ; CHECK-LABEL: @neg_signbit_use1(
 ; CHECK-NEXT:    [[S:%.*]] = lshr <2 x i32> [[X:%.*]], <i32 31, i32 poison>
 ; CHECK-NEXT:    call void @usev2i32(<2 x i32> [[S]])
-; CHECK-NEXT:    [[Z:%.*]] = zext <2 x i32> [[S]] to <2 x i64>
-; CHECK-NEXT:    [[R:%.*]] = sub nsw <2 x i64> zeroinitializer, [[Z]]
-; CHECK-NEXT:    ret <2 x i64> [[R]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i32> [[X]], <i32 31, i32 31>
+; CHECK-NEXT:    [[TMP2:%.*]] = sext <2 x i32> [[TMP1]] to <2 x i64>
+; CHECK-NEXT:    ret <2 x i64> [[TMP2]]
 ;
   %s = lshr <2 x i32> %x, <i32 31, i32 poison>
   call void @usev2i32(<2 x i32> %s)
@@ -212,6 +211,8 @@ define <2 x i64> @neg_signbit_use1(<2 x i32> %x) {
   ret <2 x i64> %r
 }
 
+; negative test - extra use
+
 define i8 @neg_signbit_use2(i5 %x) {
 ; CHECK-LABEL: @neg_signbit_use2(
 ; CHECK-NEXT:    [[S:%.*]] = lshr i5 [[X:%.*]], 4
@@ -227,6 +228,9 @@ define i8 @neg_signbit_use2(i5 %x) {
   ret i8 %r
 }
 
+; negative test - not negation
+; TODO: reduce to zext(x s> -1)
+
 define i32 @neg_not_signbit1(i8 %x) {
 ; CHECK-LABEL: @neg_not_signbit1(
 ; CHECK-NEXT:    [[TMP1:%.*]] = xor i8 [[X:%.*]], -1
@@ -240,6 +244,8 @@ define i32 @neg_not_signbit1(i8 %x) {
   ret i32 %r
 }
 
+; negative test - wrong shift amount
+
 define i32 @neg_not_signbit2(i8 %x) {
 ; CHECK-LABEL: @neg_not_signbit2(
 ; CHECK-NEXT:    [[S:%.*]] = lshr i8 [[X:%.*]], 6
@@ -253,6 +259,8 @@ define i32 @neg_not_signbit2(i8 %x) {
   ret i32 %r
 }
 
+; negative test - wrong shift opcode
+
 define i32 @neg_not_signbit3(i8 %x) {
 ; CHECK-LABEL: @neg_not_signbit3(
 ; CHECK-NEXT:    [[S:%.*]] = ashr i8 [[X:%.*]], 7
@@ -270,10 +278,9 @@ define i32 @neg_mask(i32 %x, i16 %y) {
 ; CHECK-LABEL: @neg_mask(
 ; CHECK-NEXT:    [[S:%.*]] = sext i16 [[Y:%.*]] to i32
 ; CHECK-NEXT:    [[SUB1:%.*]] = sub nsw i32 [[X:%.*]], [[S]]
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[Y]], 15
-; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[SH]] to i32
-; CHECK-NEXT:    [[SUB2:%.*]] = sub nsw i32 0, [[Z]]
-; CHECK-NEXT:    [[R:%.*]] = and i32 [[SUB1]], [[SUB2]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i16 [[Y]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = sext i16 [[TMP1]] to i32
+; CHECK-NEXT:    [[R:%.*]] = and i32 [[SUB1]], [[TMP2]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %s = sext i16 %y to i32
@@ -289,10 +296,9 @@ define i32 @neg_mask_const(i16 %x) {
 ; CHECK-LABEL: @neg_mask_const(
 ; CHECK-NEXT:    [[S:%.*]] = sext i16 [[X:%.*]] to i32
 ; CHECK-NEXT:    [[SUB1:%.*]] = sub nsw i32 1000, [[S]]
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[X]], 15
-; CHECK-NEXT:    [[Z:%.*]] = zext i16 [[SH]] to i32
-; CHECK-NEXT:    [[SUB2:%.*]] = sub nsw i32 0, [[Z]]
-; CHECK-NEXT:    [[R:%.*]] = and i32 [[SUB1]], [[SUB2]]
+; CHECK-NEXT:    [[TMP1:%.*]] = ashr i16 [[X]], 15
+; CHECK-NEXT:    [[TMP2:%.*]] = sext i16 [[TMP1]] to i32
+; CHECK-NEXT:    [[R:%.*]] = and i32 [[SUB1]], [[TMP2]]
 ; CHECK-NEXT:    ret i32 [[R]]
 ;
   %s = sext i16 %x to i32


        


More information about the llvm-commits mailing list