[llvm] d4da712 - [InstCombine] Various tests for truncating saturates and related patterns.

David Green via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 22 10:36:12 PDT 2021


Author: David Green
Date: 2021-10-22T18:36:08+01:00
New Revision: d4da71282f6e30686e3324633436d82cd6059132

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

LOG: [InstCombine] Various tests for truncating saturates and related patterns.

Added: 
    llvm/test/Transforms/InstCombine/icmp-topbitssame.ll
    llvm/test/Transforms/InstCombine/xor-ashr.ll

Modified: 
    llvm/test/Transforms/InstCombine/truncating-saturate.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll b/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll
new file mode 100644
index 000000000000..2794e1345b34
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/icmp-topbitssame.ll
@@ -0,0 +1,239 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+
+declare void @use(i8)
+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:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 8
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp eq i8 %shr2.i, %conv.i
+  ret i1 %cmp.not.i
+}
+
+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:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 8
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp eq i8 %conv.i, %shr2.i
+  ret i1 %cmp.not.i
+}
+
+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:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 8
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp ne i8 %shr2.i, %conv.i
+  ret i1 %cmp.not.i
+}
+
+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:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 8
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp ne i8 %conv.i, %shr2.i
+  ret i1 %cmp.not.i
+}
+
+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:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i64 %add, 32
+  %conv.i = trunc i64 %sh to i32
+  %conv1.i = trunc i64 %add to i32
+  %shr2.i = ashr i32 %conv1.i, 31
+  %cmp.not.i = icmp eq i32 %shr2.i, %conv.i
+  ret i1 %cmp.not.i
+}
+
+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:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i64 %add, 32
+  %conv.i = trunc i64 %sh to i32
+  %conv1.i = trunc i64 %add to i32
+  %shr2.i = ashr i32 %conv1.i, 31
+  %cmp.not.i = icmp ne i32 %shr2.i, %conv.i
+  ret i1 %cmp.not.i
+}
+
+; Negative tests
+
+define i1 @testi32i8(i32 %add) {
+; CHECK-LABEL: @testi32i8(
+; CHECK-NEXT:    [[SH:%.*]] = lshr i32 [[ADD:%.*]], 8
+; CHECK-NEXT:    [[CONV_I:%.*]] = trunc i32 [[SH]] to i8
+; CHECK-NEXT:    [[CONV1_I:%.*]] = trunc i32 [[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:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i32 %add, 8
+  %conv.i = trunc i32 %sh to i8
+  %conv1.i = trunc i32 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp eq i8 %shr2.i, %conv.i
+  ret i1 %cmp.not.i
+}
+
+define i1 @wrongimm1(i16 %add) {
+; CHECK-LABEL: @wrongimm1(
+; CHECK-NEXT:    [[SH:%.*]] = lshr i16 [[ADD:%.*]], 7
+; 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:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 7
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp eq i8 %shr2.i, %conv.i
+  ret i1 %cmp.not.i
+}
+
+define i1 @wrongimm2(i16 %add) {
+; CHECK-LABEL: @wrongimm2(
+; 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]], 6
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 8
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 6
+  %cmp.not.i = icmp eq i8 %shr2.i, %conv.i
+  ret i1 %cmp.not.i
+}
+
+define i1 @slt(i64 %add) {
+; CHECK-LABEL: @slt(
+; 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 slt i32 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i64 %add, 32
+  %conv.i = trunc i64 %sh to i32
+  %conv1.i = trunc i64 %add to i32
+  %shr2.i = ashr i32 %conv1.i, 31
+  %cmp.not.i = icmp slt i32 %shr2.i, %conv.i
+  ret i1 %cmp.not.i
+}
+
+; Use checks
+
+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:    [[SHR2_I:%.*]] = ashr i8 [[CONV1_I]], 7
+; CHECK-NEXT:    [[CMP_NOT_I:%.*]] = icmp eq i8 [[SHR2_I]], [[CONV_I]]
+; CHECK-NEXT:    call void @use(i8 [[SHR2_I]])
+; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 8
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp eq i8 %shr2.i, %conv.i
+  call void @use(i8 %shr2.i)
+  ret i1 %cmp.not.i
+}
+
+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:    call void @use(i8 [[CONV_I]])
+; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 8
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp eq i8 %shr2.i, %conv.i
+  call void @use(i8 %conv.i)
+  ret i1 %cmp.not.i
+}
+
+define i1 @extrause_la(i16 %add) {
+; CHECK-LABEL: @extrause_la(
+; 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:    call void @use(i8 [[SHR2_I]])
+; CHECK-NEXT:    call void @use(i8 [[CONV_I]])
+; CHECK-NEXT:    ret i1 [[CMP_NOT_I]]
+;
+  %sh = lshr i16 %add, 8
+  %conv.i = trunc i16 %sh to i8
+  %conv1.i = trunc i16 %add to i8
+  %shr2.i = ashr i8 %conv1.i, 7
+  %cmp.not.i = icmp eq i8 %shr2.i, %conv.i
+  call void @use(i8 %shr2.i)
+  call void @use(i8 %conv.i)
+  ret i1 %cmp.not.i
+}

diff  --git a/llvm/test/Transforms/InstCombine/truncating-saturate.ll b/llvm/test/Transforms/InstCombine/truncating-saturate.ll
index 07899b9490cf..06d2c208fd28 100644
--- a/llvm/test/Transforms/InstCombine/truncating-saturate.ll
+++ b/llvm/test/Transforms/InstCombine/truncating-saturate.ll
@@ -583,3 +583,33 @@ define i8 @C0zero(i8 %X, i8 %y, i8 %z) {
   %r = select i1 %cmp, i8 %X, i8 %f
   ret i8 %r
 }
+
+define <2 x i8> @C0zeroV(<2 x i8> %X, <2 x i8> %y, <2 x i8> %z) {
+; CHECK-LABEL: @C0zeroV(
+; CHECK-NEXT:    [[C:%.*]] = icmp slt <2 x i8> [[X:%.*]], <i8 -10, i8 -10>
+; CHECK-NEXT:    [[F:%.*]] = select <2 x i1> [[C]], <2 x i8> [[Y:%.*]], <2 x i8> [[Z:%.*]]
+; CHECK-NEXT:    ret <2 x i8> [[F]]
+;
+  %a = add <2 x i8> %X, <i8 10, i8 10>
+  %cmp = icmp ult <2 x i8> %a, zeroinitializer
+  %c = icmp slt <2 x i8> %X, <i8 -10, i8 -10>
+  %f = select <2 x i1> %c, <2 x i8> %y, <2 x i8> %z
+  %r = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %f
+  ret <2 x i8> %r
+}
+
+define <2 x i8> @C0zeroVu(<2 x i8> %X, <2 x i8> %y, <2 x i8> %z) {
+; CHECK-LABEL: @C0zeroVu(
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp slt <2 x i8> [[X:%.*]], <i8 -10, i8 -10>
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp sgt <2 x i8> [[X]], <i8 -11, i8 -1>
+; CHECK-NEXT:    [[TMP3:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> [[Y:%.*]], <2 x i8> [[X]]
+; CHECK-NEXT:    [[R:%.*]] = select <2 x i1> [[TMP2]], <2 x i8> [[Z:%.*]], <2 x i8> [[TMP3]]
+; CHECK-NEXT:    ret <2 x i8> [[R]]
+;
+  %a = add <2 x i8> %X, <i8 10, i8 10>
+  %cmp = icmp ult <2 x i8> %a, <i8 0, i8 10>
+  %c = icmp slt <2 x i8> %X, <i8 -10, i8 -10>
+  %f = select <2 x i1> %c, <2 x i8> %y, <2 x i8> %z
+  %r = select <2 x i1> %cmp, <2 x i8> %X, <2 x i8> %f
+  ret <2 x i8> %r
+}

diff  --git a/llvm/test/Transforms/InstCombine/xor-ashr.ll b/llvm/test/Transforms/InstCombine/xor-ashr.ll
new file mode 100644
index 000000000000..146206b43f1e
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/xor-ashr.ll
@@ -0,0 +1,140 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -instcombine -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+
+declare void @use16(i16)
+declare void @use32(i32)
+
+define i8 @testi8i8(i8 %add) {
+; CHECK-LABEL: @testi8i8(
+; CHECK-NEXT:    [[SH:%.*]] = ashr i8 [[ADD:%.*]], 7
+; CHECK-NEXT:    [[X:%.*]] = xor i8 [[SH]], 127
+; CHECK-NEXT:    ret i8 [[X]]
+;
+  %sh = ashr i8 %add, 7
+  %x = xor i8 %sh, 127
+  ret i8 %x
+}
+
+define i8 @testi16i8(i16 %add) {
+; CHECK-LABEL: @testi16i8(
+; CHECK-NEXT:    [[SH:%.*]] = ashr i16 [[ADD:%.*]], 15
+; CHECK-NEXT:    [[T:%.*]] = trunc i16 [[SH]] to i8
+; CHECK-NEXT:    [[X:%.*]] = xor i8 [[T]], 27
+; CHECK-NEXT:    ret i8 [[X]]
+;
+  %sh = ashr i16 %add, 15
+  %t = trunc i16 %sh to i8
+  %x = xor i8 %t, 27
+  ret i8 %x
+}
+
+define i32 @testi64i32(i64 %add) {
+; CHECK-LABEL: @testi64i32(
+; CHECK-NEXT:    [[SH:%.*]] = ashr i64 [[ADD:%.*]], 63
+; CHECK-NEXT:    [[T:%.*]] = trunc i64 [[SH]] to i32
+; CHECK-NEXT:    [[X:%.*]] = xor i32 [[T]], 127
+; CHECK-NEXT:    ret i32 [[X]]
+;
+  %sh = ashr i64 %add, 63
+  %t = trunc i64 %sh to i32
+  %x = xor i32 %t, 127
+  ret i32 %x
+}
+
+define i128 @testi128i128(i128 %add) {
+; CHECK-LABEL: @testi128i128(
+; CHECK-NEXT:    [[SH:%.*]] = ashr i128 [[ADD:%.*]], 127
+; CHECK-NEXT:    [[X:%.*]] = xor i128 [[SH]], 27
+; CHECK-NEXT:    ret i128 [[X]]
+;
+  %sh = ashr i128 %add, 127
+  %x = xor i128 %sh, 27
+  ret i128 %x
+}
+
+define <4 x i8> @testv4i16i8(<4 x i16> %add) {
+; CHECK-LABEL: @testv4i16i8(
+; CHECK-NEXT:    [[SH:%.*]] = ashr <4 x i16> [[ADD:%.*]], <i16 15, i16 15, i16 15, i16 15>
+; CHECK-NEXT:    [[T:%.*]] = trunc <4 x i16> [[SH]] to <4 x i8>
+; CHECK-NEXT:    [[X:%.*]] = xor <4 x i8> [[T]], <i8 27, i8 27, i8 27, i8 27>
+; CHECK-NEXT:    ret <4 x i8> [[X]]
+;
+  %sh = ashr <4 x i16> %add, <i16 15, i16 15, i16 15, i16 15>
+  %t = trunc <4 x i16> %sh to <4 x i8>
+  %x = xor <4 x i8> %t, <i8 27, i8 27, i8 27, i8 27>
+  ret <4 x i8> %x
+}
+
+define <4 x i8> @testv4i16i8_undef(<4 x i16> %add) {
+; CHECK-LABEL: @testv4i16i8_undef(
+; CHECK-NEXT:    [[SH:%.*]] = ashr <4 x i16> [[ADD:%.*]], <i16 15, i16 undef, i16 15, i16 15>
+; CHECK-NEXT:    [[T:%.*]] = trunc <4 x i16> [[SH]] to <4 x i8>
+; CHECK-NEXT:    [[X:%.*]] = xor <4 x i8> [[T]], <i8 27, i8 27, i8 undef, i8 27>
+; CHECK-NEXT:    ret <4 x i8> [[X]]
+;
+  %sh = ashr <4 x i16> %add, <i16 15, i16 undef, i16 15, i16 15>
+  %t = trunc <4 x i16> %sh to <4 x i8>
+  %x = xor <4 x i8> %t, <i8 27, i8 27, i8 undef, i8 27>
+  ret <4 x i8> %x
+}
+
+; Negative tests
+
+define i8 @wrongimm(i16 %add) {
+; CHECK-LABEL: @wrongimm(
+; CHECK-NEXT:    [[SH:%.*]] = ashr i16 [[ADD:%.*]], 14
+; CHECK-NEXT:    [[T:%.*]] = trunc i16 [[SH]] to i8
+; CHECK-NEXT:    [[X:%.*]] = xor i8 [[T]], 27
+; CHECK-NEXT:    ret i8 [[X]]
+;
+  %sh = ashr i16 %add, 14
+  %t = trunc i16 %sh to i8
+  %x = xor i8 %t, 27
+  ret i8 %x
+}
+
+; One use
+
+define i16 @extrause(i16 %add) {
+; CHECK-LABEL: @extrause(
+; CHECK-NEXT:    [[SH:%.*]] = ashr i16 [[ADD:%.*]], 15
+; CHECK-NEXT:    [[X:%.*]] = xor i16 [[SH]], 27
+; CHECK-NEXT:    call void @use16(i16 [[SH]])
+; CHECK-NEXT:    ret i16 [[X]]
+;
+  %sh = ashr i16 %add, 15
+  %x = xor i16 %sh, 27
+  call void @use16(i16 %sh)
+  ret i16 %x
+}
+
+define i16 @extrause_trunc1(i32 %add) {
+; CHECK-LABEL: @extrause_trunc1(
+; CHECK-NEXT:    [[SH:%.*]] = ashr i32 [[ADD:%.*]], 31
+; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[SH]] to i16
+; CHECK-NEXT:    call void @use32(i32 [[SH]])
+; CHECK-NEXT:    [[X:%.*]] = xor i16 [[T]], 127
+; CHECK-NEXT:    ret i16 [[X]]
+;
+  %sh = ashr i32 %add, 31
+  %t = trunc i32 %sh to i16
+  call void @use32(i32 %sh)
+  %x = xor i16 %t, 127
+  ret i16 %x
+}
+
+define i16 @extrause_trunc2(i32 %add) {
+; CHECK-LABEL: @extrause_trunc2(
+; CHECK-NEXT:    [[SH:%.*]] = ashr i32 [[ADD:%.*]], 31
+; CHECK-NEXT:    [[T:%.*]] = trunc i32 [[SH]] to i16
+; CHECK-NEXT:    call void @use16(i16 [[T]])
+; CHECK-NEXT:    [[X:%.*]] = xor i16 [[T]], 127
+; CHECK-NEXT:    ret i16 [[X]]
+;
+  %sh = ashr i32 %add, 31
+  %t = trunc i32 %sh to i16
+  call void @use16(i16 %t)
+  %x = xor i16 %t, 127
+  ret i16 %x
+}


        


More information about the llvm-commits mailing list