[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / SystemZ / int-sadd-05.ll
blobea2f4895da4ba5e0b6288306cd08e9c1d87e8d7d
1 ; Test additions between an i64 and a sign-extended i16 on z14.
3 ; RUN: llc < %s -mtriple=s390x-linux-gnu -mcpu=z14 | FileCheck %s
5 declare i64 @foo()
7 ; Check AGH with no displacement.
8 define zeroext i1 @f1(i64 %dummy, i64 %a, i16 *%src, i64 *%res) {
9 ; CHECK-LABEL: f1:
10 ; CHECK: agh %r3, 0(%r4)
11 ; CHECK-DAG: stg %r3, 0(%r5)
12 ; CHECK-DAG: lghi %r2, 0
13 ; CHECK-DAG: locghio %r2, 1
14 ; CHECK: br %r14
15   %half = load i16, i16 *%src
16   %b = sext i16 %half to i64
17   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
18   %val = extractvalue {i64, i1} %t, 0
19   %obit = extractvalue {i64, i1} %t, 1
20   store i64 %val, i64 *%res
21   ret i1 %obit
24 ; Check the high end of the aligned AGH range.
25 define zeroext i1 @f4(i64 %dummy, i64 %a, i16 *%src, i64 *%res) {
26 ; CHECK-LABEL: f4:
27 ; CHECK: agh %r3, 524286(%r4)
28 ; CHECK-DAG: stg %r3, 0(%r5)
29 ; CHECK-DAG: lghi %r2, 0
30 ; CHECK-DAG: locghio %r2, 1
31 ; CHECK: br %r14
32   %ptr = getelementptr i16, i16 *%src, i64 262143
33   %half = load i16, i16 *%ptr
34   %b = sext i16 %half to i64
35   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
36   %val = extractvalue {i64, i1} %t, 0
37   %obit = extractvalue {i64, i1} %t, 1
38   store i64 %val, i64 *%res
39   ret i1 %obit
42 ; Check the next halfword up, which needs separate address logic.
43 ; Other sequences besides this one would be OK.
44 define zeroext i1 @f5(i64 %dummy, i64 %a, i16 *%src, i64 *%res) {
45 ; CHECK-LABEL: f5:
46 ; CHECK: agfi %r4, 524288
47 ; CHECK: agh %r3, 0(%r4)
48 ; CHECK-DAG: stg %r3, 0(%r5)
49 ; CHECK-DAG: lghi %r2, 0
50 ; CHECK-DAG: locghio %r2, 1
51 ; CHECK: br %r14
52   %ptr = getelementptr i16, i16 *%src, i64 262144
53   %half = load i16, i16 *%ptr
54   %b = sext i16 %half to i64
55   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
56   %val = extractvalue {i64, i1} %t, 0
57   %obit = extractvalue {i64, i1} %t, 1
58   store i64 %val, i64 *%res
59   ret i1 %obit
62 ; Check the high end of the negative aligned AGH range.
63 define zeroext i1 @f6(i64 %dummy, i64 %a, i16 *%src, i64 *%res) {
64 ; CHECK-LABEL: f6:
65 ; CHECK: agh %r3, -2(%r4)
66 ; CHECK-DAG: stg %r3, 0(%r5)
67 ; CHECK-DAG: lghi %r2, 0
68 ; CHECK-DAG: locghio %r2, 1
69 ; CHECK: br %r14
70   %ptr = getelementptr i16, i16 *%src, i64 -1
71   %half = load i16, i16 *%ptr
72   %b = sext i16 %half to i64
73   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
74   %val = extractvalue {i64, i1} %t, 0
75   %obit = extractvalue {i64, i1} %t, 1
76   store i64 %val, i64 *%res
77   ret i1 %obit
80 ; Check the low end of the AGH range.
81 define zeroext i1 @f7(i64 %dummy, i64 %a, i16 *%src, i64 *%res) {
82 ; CHECK-LABEL: f7:
83 ; CHECK: agh %r3, -524288(%r4)
84 ; CHECK-DAG: stg %r3, 0(%r5)
85 ; CHECK-DAG: lghi %r2, 0
86 ; CHECK-DAG: locghio %r2, 1
87 ; CHECK: br %r14
88   %ptr = getelementptr i16, i16 *%src, i64 -262144
89   %half = load i16, i16 *%ptr
90   %b = sext i16 %half to i64
91   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
92   %val = extractvalue {i64, i1} %t, 0
93   %obit = extractvalue {i64, i1} %t, 1
94   store i64 %val, i64 *%res
95   ret i1 %obit
98 ; Check the next halfword down, which needs separate address logic.
99 ; Other sequences besides this one would be OK.
100 define zeroext i1 @f8(i64 %dummy, i64 %a, i16 *%src, i64 *%res) {
101 ; CHECK-LABEL: f8:
102 ; CHECK: agfi %r4, -524290
103 ; CHECK: agh %r3, 0(%r4)
104 ; CHECK-DAG: stg %r3, 0(%r5)
105 ; CHECK-DAG: lghi %r2, 0
106 ; CHECK-DAG: locghio %r2, 1
107 ; CHECK: br %r14
108   %ptr = getelementptr i16, i16 *%src, i64 -262145
109   %half = load i16, i16 *%ptr
110   %b = sext i16 %half to i64
111   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
112   %val = extractvalue {i64, i1} %t, 0
113   %obit = extractvalue {i64, i1} %t, 1
114   store i64 %val, i64 *%res
115   ret i1 %obit
118 ; Check that AGH allows an index.
119 define zeroext i1 @f9(i64 %src, i64 %index, i64 %a, i64 *%res) {
120 ; CHECK-LABEL: f9:
121 ; CHECK: agh %r4, 524284({{%r3,%r2|%r2,%r3}})
122 ; CHECK-DAG: stg %r4, 0(%r5)
123 ; CHECK-DAG: lghi %r2, 0
124 ; CHECK-DAG: locghio %r2, 1
125 ; CHECK: br %r14
126   %add1 = add i64 %src, %index
127   %add2 = add i64 %add1, 524284
128   %ptr = inttoptr i64 %add2 to i16 *
129   %half = load i16, i16 *%ptr
130   %b = sext i16 %half to i64
131   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
132   %val = extractvalue {i64, i1} %t, 0
133   %obit = extractvalue {i64, i1} %t, 1
134   store i64 %val, i64 *%res
135   ret i1 %obit
138 ; Check using the overflow result for a branch.
139 define void @f11(i64 %dummy, i64 %a, i16 *%src, i64 *%res) {
140 ; CHECK-LABEL: f11:
141 ; CHECK: agh %r3, 0(%r4)
142 ; CHECK: stg %r3, 0(%r5)
143 ; CHECK: jgo foo@PLT
144 ; CHECK: br %r14
145   %half = load i16, i16 *%src
146   %b = sext i16 %half to i64
147   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
148   %val = extractvalue {i64, i1} %t, 0
149   %obit = extractvalue {i64, i1} %t, 1
150   store i64 %val, i64 *%res
151   br i1 %obit, label %call, label %exit
153 call:
154   tail call i64 @foo()
155   br label %exit
157 exit:
158   ret void
161 ; ... and the same with the inverted direction.
162 define void @f12(i64 %dummy, i64 %a, i16 *%src, i64 *%res) {
163 ; CHECK-LABEL: f12:
164 ; CHECK: agh %r3, 0(%r4)
165 ; CHECK: stg %r3, 0(%r5)
166 ; CHECK: jgno foo@PLT
167 ; CHECK: br %r14
168   %half = load i16, i16 *%src
169   %b = sext i16 %half to i64
170   %t = call {i64, i1} @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
171   %val = extractvalue {i64, i1} %t, 0
172   %obit = extractvalue {i64, i1} %t, 1
173   store i64 %val, i64 *%res
174   br i1 %obit, label %exit, label %call
176 call:
177   tail call i64 @foo()
178   br label %exit
180 exit:
181   ret void
185 declare {i64, i1} @llvm.sadd.with.overflow.i64(i64, i64) nounwind readnone