[llvm] 11630db - [InstCombine] Fold BW/2+1 tops bits are same pattern

David Green via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 29 04:30:26 PDT 2021


Author: David Green
Date: 2021-10-29T12:30:20+01:00
New Revision: 11630dbbc3697283c722ebfde1cd322841666b33

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

LOG: [InstCombine] Fold BW/2+1 tops bits are same pattern

Match "icmp eq (trunc (lsr A, BW), (ashr (trunc A), BW-1))", which checks
the top BW/2 + 1 bits are all the same. Create "A >=s INT_MIN && A <=s
INT_MAX", which we generate as "icmp ult (add A, 2^BW-1), 2^BW" to skip
a few steps of instcombining.
https://alive2.llvm.org/ce/z/NjH6Ty
https://alive2.llvm.org/ce/z/_fEQ9P

Differential Revision: https://reviews.llvm.org/D109155

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
    llvm/test/Transforms/InstCombine/icmp-topbitssame.ll
    llvm/test/Transforms/InstCombine/truncating-saturate.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
index a2db1bc83e76..4634bd07db31 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCompares.cpp
@@ -4586,6 +4586,22 @@ Instruction *InstCombinerImpl::foldICmpEquality(ICmpInst &I) {
         : new ICmpInst(ICmpInst::ICMP_UGT, CtPop, ConstantInt::get(Ty, 1));
   }
 
+  // Match icmp eq (trunc (lshr A, BW), (ashr (trunc A), BW-1)), which checks the
+  // top BW/2 + 1 bits are all the same. Create "A >=s INT_MIN && A <=s INT_MAX",
+  // which we generate as "icmp ult (add A, 2^(BW-1)), 2^BW" to skip a few steps
+  // of instcombine.
+  unsigned BitWidth = Op0->getType()->getScalarSizeInBits();
+  if (match(Op0, m_AShr(m_Trunc(m_Value(A)), m_SpecificInt(BitWidth - 1))) &&
+      match(Op1, m_Trunc(m_LShr(m_Specific(A), m_SpecificInt(BitWidth)))) &&
+      A->getType()->getScalarSizeInBits() == BitWidth * 2 &&
+      (I.getOperand(0)->hasOneUse() || I.getOperand(1)->hasOneUse())) {
+    APInt C = APInt::getOneBitSet(BitWidth * 2, BitWidth - 1);
+    Value *Add = Builder.CreateAdd(A, ConstantInt::get(A->getType(), C));
+    return new ICmpInst(Pred == ICmpInst::ICMP_EQ ? ICmpInst::ICMP_ULT
+                                                  : ICmpInst::ICMP_UGE,
+                        Add, ConstantInt::get(A->getType(), C.shl(1)));
+  }
+
   return nullptr;
 }
 

diff  --git a/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll b/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll
index 2794e1345b34..80344391ae7f 100644
--- a/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll
+++ b/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll
@@ -7,11 +7,8 @@ declare void @use16(i16)
 
 define i1 @testi16i8(i16 %add) {
 ; CHECK-LABEL: @testi16i8(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[ADD:%.*]], 128
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i16 [[TMP1]], 256
 ; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
 ;
   %sh = lshr i16 %add, 8
@@ -24,11 +21,8 @@ define i1 @testi16i8(i16 %add) {
 
 define i1 @testi16i8_com(i16 %add) {
 ; CHECK-LABEL: @testi16i8_com(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[ADD:%.*]], 128
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i16 [[TMP1]], 256
 ; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
 ;
   %sh = lshr i16 %add, 8
@@ -41,11 +35,8 @@ define i1 @testi16i8_com(i16 %add) {
 
 define i1 @testi16i8_ne(i16 %add) {
 ; CHECK-LABEL: @testi16i8_ne(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ne i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[ADD:%.*]], 128
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ugt i16 [[TMP1]], 255
 ; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
 ;
   %sh = lshr i16 %add, 8
@@ -58,11 +49,8 @@ define i1 @testi16i8_ne(i16 %add) {
 
 define i1 @testi16i8_ne_com(i16 %add) {
 ; CHECK-LABEL: @testi16i8_ne_com(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ne i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[ADD:%.*]], 128
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ugt i16 [[TMP1]], 255
 ; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
 ;
   %sh = lshr i16 %add, 8
@@ -75,11 +63,8 @@ define i1 @testi16i8_ne_com(i16 %add) {
 
 define i1 @testi64i32(i64 %add) {
 ; CHECK-LABEL: @testi64i32(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD:%.*]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ADD:%.*]], 2147483648
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i64 [[TMP1]], 4294967296
 ; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
 ;
   %sh = lshr i64 %add, 32
@@ -92,11 +77,8 @@ define i1 @testi64i32(i64 %add) {
 
 define i1 @testi64i32_ne(i64 %add) {
 ; CHECK-LABEL: @testi64i32_ne(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD:%.*]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ne i32 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ADD:%.*]], 2147483648
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ugt i64 [[TMP1]], 4294967295
 ; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
 ;
   %sh = lshr i64 %add, 32
@@ -181,11 +163,10 @@ define i1 @slt(i64 %add) {
 
 define i1 @extrause_a(i16 %add) {
 ; CHECK-LABEL: @extrause_a(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
+; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD:%.*]] to i8
 ; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[ADD]], 128
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i16 [[TMP1]], 256
 ; CHECK-NEXT:    call void @use(i8 [[SHR2_I]])
 ; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
 ;
@@ -202,9 +183,8 @@ define i1 @extrause_l(i16 %add) {
 ; CHECK-LABEL: @extrause_l(
 ; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
 ; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[ADD]], 128
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i16 [[TMP1]], 256
 ; CHECK-NEXT:    call void @use(i8 [[CONV_I]])
 ; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
 ;

diff  --git a/llvm/test/Transforms/InstCombine/truncating-saturate.ll b/llvm/test/Transforms/InstCombine/truncating-saturate.ll
index 154a69016f6a..d83c2675758d 100644
--- a/llvm/test/Transforms/InstCombine/truncating-saturate.ll
+++ b/llvm/test/Transforms/InstCombine/truncating-saturate.ll
@@ -8,15 +8,12 @@ declare void @use1(i1)
 
 define i8 @testi16i8(i16 %add) {
 ; CHECK-LABEL: @testi16i8(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i8 127, i8 -128
-; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i8 [[CONV1_I]], i8 [[XOR_I]]
-; CHECK-NEXT:    ret i8 [[COND_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i16 [[ADD:%.*]], -128
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i16 [[ADD]], i16 -128
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i16 [[TMP2]], 127
+; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i16 [[TMP2]], i16 127
+; CHECK-NEXT:    [[TMP5:%.*]] = trunc i16 [[TMP4]] to i8
+; CHECK-NEXT:    ret i8 [[TMP5]]
 ;
   %sh = lshr i16 %add, 8
   %conv.i = trunc i16 %sh to i8
@@ -32,15 +29,12 @@ define i8 @testi16i8(i16 %add) {
 
 define i32 @testi64i32(i64 %add) {
 ; CHECK-LABEL: @testi64i32(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD:%.*]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648
-; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]]
-; CHECK-NEXT:    ret i32 [[COND_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[ADD:%.*]], -2147483648
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i64 [[ADD]], i64 -2147483648
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i64 [[TMP2]], 2147483647
+; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i64 [[TMP2]], i64 2147483647
+; CHECK-NEXT:    [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32
+; CHECK-NEXT:    ret i32 [[TMP5]]
 ;
   %sh = lshr i64 %add, 32
   %conv.i = trunc i64 %sh to i32
@@ -145,18 +139,8 @@ define i16 @testtrunclowhigh(i32 %add, i16 %low, i16 %high) {
 
 define i32 @testi64i32addsat(i32 %a, i32 %b) {
 ; CHECK-LABEL: @testi64i32addsat(
-; CHECK-NEXT:    [[SA:%.*]] = sext i32 [[A:%.*]] to i64
-; CHECK-NEXT:    [[SB:%.*]] = sext i32 [[B:%.*]] to i64
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw i64 [[SA]], [[SB]]
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648
-; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]]
-; CHECK-NEXT:    ret i32 [[COND_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 @llvm.sadd.sat.i32(i32 [[A:%.*]], i32 [[B:%.*]])
+; CHECK-NEXT:    ret i32 [[TMP1]]
 ;
   %sa = sext i32 %a to i64
   %sb = sext i32 %b to i64
@@ -175,15 +159,12 @@ define i32 @testi64i32addsat(i32 %a, i32 %b) {
 
 define <4 x i8> @testv4i16i8(<4 x i16> %add) {
 ; CHECK-LABEL: @testv4i16i8(
-; CHECK-NEXT:    [[SH:%.*]] = lshr <4 x i16> [[ADD:%.*]], <i16 8, i16 8, i16 8, i16 8>
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc <4 x i16> [[SH]] to <4 x i8>
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc <4 x i16> [[ADD]] to <4 x i8>
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr <4 x i8> [[CONV1_I]], <i8 7, i8 7, i8 7, i8 7>
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq <4 x i8> [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i16> [[ADD]], <i16 -1, i16 -1, i16 -1, i16 -1>
-; CHECK-NEXT:    [[XOR_I:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> <i8 127, i8 127, i8 127, i8 127>, <4 x i8> <i8 -128, i8 -128, i8 -128, i8 -128>
-; CHECK-NEXT:    [[COND_I:%.*]] = select <4 x i1> [[CMP_NOT_I]], <4 x i8> [[CONV1_I]], <4 x i8> [[XOR_I]]
-; CHECK-NEXT:    ret <4 x i8> [[COND_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i16> [[ADD:%.*]], <i16 -128, i16 -128, i16 -128, i16 -128>
+; CHECK-NEXT:    [[TMP2:%.*]] = select <4 x i1> [[TMP1]], <4 x i16> [[ADD]], <4 x i16> <i16 -128, i16 -128, i16 -128, i16 -128>
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt <4 x i16> [[TMP2]], <i16 127, i16 127, i16 127, i16 127>
+; CHECK-NEXT:    [[TMP4:%.*]] = select <4 x i1> [[TMP3]], <4 x i16> [[TMP2]], <4 x i16> <i16 127, i16 127, i16 127, i16 127>
+; CHECK-NEXT:    [[TMP5:%.*]] = trunc <4 x i16> [[TMP4]] to <4 x i8>
+; CHECK-NEXT:    ret <4 x i8> [[TMP5]]
 ;
   %sh = lshr <4 x i16> %add, <i16 8, i16 8, i16 8, i16 8>
   %conv.i = trunc <4 x i16> %sh to <4 x i8>
@@ -199,18 +180,8 @@ define <4 x i8> @testv4i16i8(<4 x i16> %add) {
 
 define <4 x i8> @testv4i16i8add(<4 x i8> %a, <4 x i8> %b) {
 ; CHECK-LABEL: @testv4i16i8add(
-; CHECK-NEXT:    [[SA:%.*]] = sext <4 x i8> [[A:%.*]] to <4 x i16>
-; CHECK-NEXT:    [[SB:%.*]] = sext <4 x i8> [[B:%.*]] to <4 x i16>
-; CHECK-NEXT:    [[ADD:%.*]] = add nsw <4 x i16> [[SA]], [[SB]]
-; CHECK-NEXT:    [[SH:%.*]] = lshr <4 x i16> [[ADD]], <i16 8, i16 8, i16 8, i16 8>
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc <4 x i16> [[SH]] to <4 x i8>
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc <4 x i16> [[ADD]] to <4 x i8>
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr <4 x i8> [[CONV1_I]], <i8 7, i8 7, i8 7, i8 7>
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq <4 x i8> [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt <4 x i16> [[ADD]], <i16 -1, i16 -1, i16 -1, i16 -1>
-; CHECK-NEXT:    [[XOR_I:%.*]] = select <4 x i1> [[TMP1]], <4 x i8> <i8 127, i8 127, i8 127, i8 127>, <4 x i8> <i8 -128, i8 -128, i8 -128, i8 -128>
-; CHECK-NEXT:    [[COND_I:%.*]] = select <4 x i1> [[CMP_NOT_I]], <4 x i8> [[CONV1_I]], <4 x i8> [[XOR_I]]
-; CHECK-NEXT:    ret <4 x i8> [[COND_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = call <4 x i8> @llvm.sadd.sat.v4i8(<4 x i8> [[A:%.*]], <4 x i8> [[B:%.*]])
+; CHECK-NEXT:    ret <4 x i8> [[TMP1]]
 ;
   %sa = sext <4 x i8> %a to <4 x i16>
   %sb = sext <4 x i8> %b to <4 x i16>
@@ -229,15 +200,12 @@ define <4 x i8> @testv4i16i8add(<4 x i8> %a, <4 x i8> %b) {
 
 define i8 @testi16i8_revcmp(i16 %add) {
 ; CHECK-LABEL: @testi16i8_revcmp(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i8 127, i8 -128
-; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i8 [[CONV1_I]], i8 [[XOR_I]]
-; CHECK-NEXT:    ret i8 [[COND_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i16 [[ADD:%.*]], -128
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i16 [[ADD]], i16 -128
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i16 [[TMP2]], 127
+; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i16 [[TMP2]], i16 127
+; CHECK-NEXT:    [[TMP5:%.*]] = trunc i16 [[TMP4]] to i8
+; CHECK-NEXT:    ret i8 [[TMP5]]
 ;
   %sh = lshr i16 %add, 8
   %conv.i = trunc i16 %sh to i8
@@ -253,15 +221,12 @@ define i8 @testi16i8_revcmp(i16 %add) {
 
 define i8 @testi16i8_revselect(i16 %add) {
 ; CHECK-LABEL: @testi16i8_revselect(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I_NOT:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i8 127, i8 -128
-; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I_NOT]], i8 [[CONV1_I]], i8 [[XOR_I]]
-; CHECK-NEXT:    ret i8 [[COND_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i16 [[ADD:%.*]], -128
+; CHECK-NEXT:    [[TMP2:%.*]] = select i1 [[TMP1]], i16 [[ADD]], i16 -128
+; CHECK-NEXT:    [[TMP3:%.*]] = icmp slt i16 [[TMP2]], 127
+; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP3]], i16 [[TMP2]], i16 127
+; CHECK-NEXT:    [[TMP5:%.*]] = trunc i16 [[TMP4]] to i8
+; CHECK-NEXT:    ret i8 [[TMP5]]
 ;
   %sh = lshr i16 %add, 8
   %conv.i = trunc i16 %sh to i8
@@ -368,11 +333,9 @@ define i8 @badimm2(i16 %add) {
 
 define i8 @badimm3(i16 %add) {
 ; CHECK-LABEL: @badimm3(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD:%.*]] to i8
+; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[ADD]], 128
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i16 [[TMP1]], 256
 ; CHECK-NEXT:    [[SHR4_I:%.*]] = ashr i16 [[ADD]], 14
 ; CHECK-NEXT:    [[CONV5_I:%.*]] = trunc i16 [[SHR4_I]] to i8
 ; CHECK-NEXT:    [[XOR_I:%.*]] = xor i8 [[CONV5_I]], 127
@@ -393,15 +356,12 @@ define i8 @badimm3(i16 %add) {
 
 define i8 @badimm4(i16 %add) {
 ; CHECK-LABEL: @badimm4(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 8
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i16 [[SH]] to i8
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i16 [[ADD]] to i8
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i16 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i8 126, i8 -127
-; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i8 [[CONV1_I]], i8 [[XOR_I]]
-; CHECK-NEXT:    ret i8 [[COND_I]]
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt i16 [[ADD:%.*]], -128
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i16 [[ADD]], 127
+; CHECK-NEXT:    [[TMP3:%.*]] = trunc i16 [[ADD]] to i8
+; CHECK-NEXT:    [[TMP4:%.*]] = select i1 [[TMP1]], i8 -127, i8 [[TMP3]]
+; CHECK-NEXT:    [[TMP5:%.*]] = select i1 [[TMP2]], i8 126, i8 [[TMP4]]
+; CHECK-NEXT:    ret i8 [[TMP5]]
 ;
   %sh = lshr i16 %add, 8
   %conv.i = trunc i16 %sh to i8
@@ -419,13 +379,11 @@ define i8 @badimm4(i16 %add) {
 
 define i32 @oneusexor(i64 %add) {
 ; CHECK-LABEL: @oneusexor(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD:%.*]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648
+; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD:%.*]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ADD]], 2147483648
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i64 [[TMP1]], 4294967296
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i64 [[ADD]], -1
+; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP2]], i32 2147483647, i32 -2147483648
 ; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]]
 ; CHECK-NEXT:    call void @use(i32 [[XOR_I]])
 ; CHECK-NEXT:    ret i32 [[COND_I]]
@@ -445,13 +403,11 @@ define i32 @oneusexor(i64 %add) {
 
 define i32 @oneuseconv(i64 %add) {
 ; CHECK-LABEL: @oneuseconv(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD:%.*]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648
+; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD:%.*]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ADD]], 2147483648
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i64 [[TMP1]], 4294967296
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i64 [[ADD]], -1
+; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP2]], i32 2147483647, i32 -2147483648
 ; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]]
 ; CHECK-NEXT:    call void @use(i32 [[CONV1_I]])
 ; CHECK-NEXT:    ret i32 [[COND_I]]
@@ -471,13 +427,11 @@ define i32 @oneuseconv(i64 %add) {
 
 define i32 @oneusecmp(i64 %add) {
 ; CHECK-LABEL: @oneusecmp(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD:%.*]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648
+; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD:%.*]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ADD]], 2147483648
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i64 [[TMP1]], 4294967296
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i64 [[ADD]], -1
+; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP2]], i32 2147483647, i32 -2147483648
 ; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]]
 ; CHECK-NEXT:    call void @use1(i1 [[CMP_NOT_I]])
 ; CHECK-NEXT:    ret i32 [[COND_I]]
@@ -497,13 +451,11 @@ define i32 @oneusecmp(i64 %add) {
 
 define i32 @oneuseboth(i64 %add) {
 ; CHECK-LABEL: @oneuseboth(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD:%.*]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648
+; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD:%.*]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ADD]], 2147483648
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i64 [[TMP1]], 4294967296
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i64 [[ADD]], -1
+; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP2]], i32 2147483647, i32 -2147483648
 ; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]]
 ; CHECK-NEXT:    call void @use(i32 [[XOR_I]])
 ; CHECK-NEXT:    call void @use(i32 [[CONV1_I]])
@@ -525,13 +477,11 @@ define i32 @oneuseboth(i64 %add) {
 
 define i32 @oneusethree(i64 %add) {
 ; CHECK-LABEL: @oneusethree(
-; CHECK-NEXT:    [[SH:%.*]] = lshr i64 [[ADD:%.*]], 32
-; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i64 [[SH]] to i32
-; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD]] to i32
-; CHECK-NEXT:    [[SHR2_I:%.*]] = ashr i32 [[CONV1_I]], 31
-; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i32 [[SHR2_I]], [[CONV_I]]
-; CHECK-NEXT:    [[TMP1:%.*]] = icmp sgt i64 [[ADD]], -1
-; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP1]], i32 2147483647, i32 -2147483648
+; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i64 [[ADD:%.*]] to i32
+; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[ADD]], 2147483648
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp ult i64 [[TMP1]], 4294967296
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt i64 [[ADD]], -1
+; CHECK-NEXT:    [[XOR_I:%.*]] = select i1 [[TMP2]], i32 2147483647, i32 -2147483648
 ; CHECK-NEXT:    [[COND_I:%.*]] = select i1 [[CMP_NOT_I]], i32 [[CONV1_I]], i32 [[XOR_I]]
 ; CHECK-NEXT:    call void @use(i32 [[XOR_I]])
 ; CHECK-NEXT:    call void @use(i32 [[CONV1_I]])


        


More information about the llvm-commits mailing list