[InstCombine] Signed saturation patterns
[llvm-core.git] / test / Transforms / InstCombine / high-bit-signmask-with-trunc.ll
blob034c285dd1ff17943864f4dd7a6a6af8321beab6
1 ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2 ; RUN: opt %s -instcombine -S | FileCheck %s
4 define i32 @t0(i64 %x) {
5 ; CHECK-LABEL: @t0(
6 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[X:%.*]], 63
7 ; CHECK-NEXT:    [[R:%.*]] = trunc i64 [[TMP1]] to i32
8 ; CHECK-NEXT:    ret i32 [[R]]
10   %t0 = lshr i64 %x, 63
11   %t1 = trunc i64 %t0 to i32
12   %r = sub i32 0, %t1
13   ret i32 %r
15 define i32 @t1_exact(i64 %x) {
16 ; CHECK-LABEL: @t1_exact(
17 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr exact i64 [[X:%.*]], 63
18 ; CHECK-NEXT:    [[R:%.*]] = trunc i64 [[TMP1]] to i32
19 ; CHECK-NEXT:    ret i32 [[R]]
21   %t0 = lshr exact i64 %x, 63
22   %t1 = trunc i64 %t0 to i32
23   %r = sub i32 0, %t1
24   ret i32 %r
26 define i32 @t2(i64 %x) {
27 ; CHECK-LABEL: @t2(
28 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr i64 [[X:%.*]], 63
29 ; CHECK-NEXT:    [[R:%.*]] = trunc i64 [[TMP1]] to i32
30 ; CHECK-NEXT:    ret i32 [[R]]
32   %t0 = ashr i64 %x, 63
33   %t1 = trunc i64 %t0 to i32
34   %r = sub i32 0, %t1
35   ret i32 %r
37 define i32 @t3_exact(i64 %x) {
38 ; CHECK-LABEL: @t3_exact(
39 ; CHECK-NEXT:    [[TMP1:%.*]] = lshr exact i64 [[X:%.*]], 63
40 ; CHECK-NEXT:    [[R:%.*]] = trunc i64 [[TMP1]] to i32
41 ; CHECK-NEXT:    ret i32 [[R]]
43   %t0 = ashr exact i64 %x, 63
44   %t1 = trunc i64 %t0 to i32
45   %r = sub i32 0, %t1
46   ret i32 %r
49 define <2 x i32> @t4(<2 x i64> %x) {
50 ; CHECK-LABEL: @t4(
51 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr <2 x i64> [[X:%.*]], <i64 63, i64 63>
52 ; CHECK-NEXT:    [[R:%.*]] = trunc <2 x i64> [[TMP1]] to <2 x i32>
53 ; CHECK-NEXT:    ret <2 x i32> [[R]]
55   %t0 = lshr <2 x i64> %x, <i64 63, i64 63>
56   %t1 = trunc <2 x i64> %t0 to <2 x i32>
57   %r = sub <2 x i32> zeroinitializer, %t1
58   ret <2 x i32> %r
61 define <2 x i32> @t5(<2 x i64> %x) {
62 ; CHECK-LABEL: @t5(
63 ; CHECK-NEXT:    [[T0:%.*]] = lshr <2 x i64> [[X:%.*]], <i64 63, i64 undef>
64 ; CHECK-NEXT:    [[T1:%.*]] = trunc <2 x i64> [[T0]] to <2 x i32>
65 ; CHECK-NEXT:    [[R:%.*]] = sub <2 x i32> <i32 0, i32 undef>, [[T1]]
66 ; CHECK-NEXT:    ret <2 x i32> [[R]]
68   %t0 = lshr <2 x i64> %x, <i64 63, i64 undef>
69   %t1 = trunc <2 x i64> %t0 to <2 x i32>
70   %r = sub <2 x i32> <i32 0, i32 undef>, %t1
71   ret <2 x i32> %r
74 declare void @use64(i64)
75 declare void @use32(i32)
77 define i32 @t6(i64 %x) {
78 ; CHECK-LABEL: @t6(
79 ; CHECK-NEXT:    [[T0:%.*]] = lshr i64 [[X:%.*]], 63
80 ; CHECK-NEXT:    call void @use64(i64 [[T0]])
81 ; CHECK-NEXT:    [[TMP1:%.*]] = ashr i64 [[X]], 63
82 ; CHECK-NEXT:    [[R:%.*]] = trunc i64 [[TMP1]] to i32
83 ; CHECK-NEXT:    ret i32 [[R]]
85   %t0 = lshr i64 %x, 63
86   call void @use64(i64 %t0)
87   %t1 = trunc i64 %t0 to i32
88   %r = sub i32 0, %t1
89   ret i32 %r
92 define i32 @n7(i64 %x) {
93 ; CHECK-LABEL: @n7(
94 ; CHECK-NEXT:    [[T0:%.*]] = lshr i64 [[X:%.*]], 63
95 ; CHECK-NEXT:    [[T1:%.*]] = trunc i64 [[T0]] to i32
96 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
97 ; CHECK-NEXT:    [[R:%.*]] = sub nsw i32 0, [[T1]]
98 ; CHECK-NEXT:    ret i32 [[R]]
100   %t0 = lshr i64 %x, 63
101   %t1 = trunc i64 %t0 to i32
102   call void @use32(i32 %t1)
103   %r = sub i32 0, %t1
104   ret i32 %r
107 define i32 @n8(i64 %x) {
108 ; CHECK-LABEL: @n8(
109 ; CHECK-NEXT:    [[T0:%.*]] = lshr i64 [[X:%.*]], 63
110 ; CHECK-NEXT:    call void @use64(i64 [[T0]])
111 ; CHECK-NEXT:    [[T1:%.*]] = trunc i64 [[T0]] to i32
112 ; CHECK-NEXT:    call void @use32(i32 [[T1]])
113 ; CHECK-NEXT:    [[R:%.*]] = sub nsw i32 0, [[T1]]
114 ; CHECK-NEXT:    ret i32 [[R]]
116   %t0 = lshr i64 %x, 63
117   call void @use64(i64 %t0)
118   %t1 = trunc i64 %t0 to i32
119   call void @use32(i32 %t1)
120   %r = sub i32 0, %t1
121   ret i32 %r
124 define i32 @n9(i64 %x) {
125 ; CHECK-LABEL: @n9(
126 ; CHECK-NEXT:    [[T0:%.*]] = lshr i64 [[X:%.*]], 62
127 ; CHECK-NEXT:    [[T1:%.*]] = trunc i64 [[T0]] to i32
128 ; CHECK-NEXT:    [[R:%.*]] = sub nsw i32 0, [[T1]]
129 ; CHECK-NEXT:    ret i32 [[R]]
131   %t0 = lshr i64 %x, 62
132   %t1 = trunc i64 %t0 to i32
133   %r = sub i32 0, %t1
134   ret i32 %r
137 define i32 @n10(i64 %x) {
138 ; CHECK-LABEL: @n10(
139 ; CHECK-NEXT:    [[T0:%.*]] = lshr i64 [[X:%.*]], 63
140 ; CHECK-NEXT:    [[T1:%.*]] = trunc i64 [[T0]] to i32
141 ; CHECK-NEXT:    [[R:%.*]] = xor i32 [[T1]], 1
142 ; CHECK-NEXT:    ret i32 [[R]]
144   %t0 = lshr i64 %x, 63
145   %t1 = trunc i64 %t0 to i32
146   %r = sub i32 1, %t1
147   ret i32 %r