[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / ARM / CGP / arm-cgp-calls.ll
blob8d58c8e69a5567c46402f5ef965e32624b82c201
1 ; RUN: llc -mtriple=thumbv8 -arm-disable-cgp=false %s -o - | FileCheck %s
2 ; RUN: llc -mtriple=armv8 -arm-disable-cgp=false %s -o - | FileCheck %s
4 ; Check that the pass doesn't try to promote the immediate parameters.
5 ; CHECK-LABEL: call_with_imms
6 ; CHECK-NOT:   uxt
7 define i8 @call_with_imms(i8* %arg) {
8   %call = tail call arm_aapcs_vfpcc zeroext i8 @dummy2(i8* nonnull %arg, i8 zeroext 0, i8 zeroext 0)
9   %cmp = icmp eq i8 %call, 0
10   %res = select i1 %cmp, i8 %call, i8 1
11   ret i8 %res
14 ; Test that the call result is still extended.
15 ; CHECK-LABEL: test_call:
16 ; CHECK: bl
17 ; CHECK-NEXT: sxtb r1, r0
18 define i16 @test_call(i8 zeroext %arg) {
19   %call = call i8 @dummy_i8(i8 %arg)
20   %cmp = icmp ult i8 %call, 128
21   %conv = zext i1 %cmp to i16
22   ret i16 %conv
25 ; CHECK-LABEL: promote_i8_sink_i16_1
26 ; CHECK: bl dummy_i8
27 ; CHECK: add{{.*}} r0, #1
28 ; CHECK-NOT: uxt
29 ; CHECK: cmp r0
30 define i16 @promote_i8_sink_i16_1(i8 zeroext %arg0, i16 zeroext %arg1, i16 zeroext %arg2) {
31   %call = tail call zeroext i8 @dummy_i8(i8 %arg0)
32   %add = add nuw i8 %call, 1
33   %conv = zext i8 %add to i16
34   %cmp = icmp ne i16 %conv, %arg1
35   %sel = select i1 %cmp, i16 %arg1, i16 %arg2
36   %res = tail call zeroext i16 @dummy3(i16 %sel)
37   ret i16 %res
40 ; CHECK-LABEL: promote_i8_sink_i16_2
41 ; CHECK: bl dummy_i8
42 ; CHECK: add{{.*}} r0, #1
43 ; CHECK-NOT: uxt
44 ; CHECK: cmp r0
45 define i16 @promote_i8_sink_i16_2(i8 zeroext %arg0, i8 zeroext %arg1, i16 zeroext %arg2) {
46   %call = tail call zeroext i8 @dummy_i8(i8 %arg0)
47   %add = add nuw i8 %call, 1
48   %cmp = icmp ne i8 %add, %arg1
49   %conv = zext i8 %arg1 to i16
50   %sel = select i1 %cmp, i16 %conv, i16 %arg2
51   %res = tail call zeroext i16 @dummy3(i16 %sel)
52   ret i16 %res
55 @uc = global i8 42, align 1
56 @LL = global i64 0, align 8
58 ; CHECK-LABEL: zext_i64
59 ; CHECK: ldrb
60 ; CHECK: strd
61 define void @zext_i64() {
62 entry:
63   %0 = load i8, i8* @uc, align 1
64   %conv = zext i8 %0 to i64
65   store i64 %conv, i64* @LL, align 8
66   %cmp = icmp eq i8 %0, 42
67   %conv1 = zext i1 %cmp to i32
68   %call = tail call i32 bitcast (i32 (...)* @assert to i32 (i32)*)(i32 %conv1)
69   ret void
72 @a = global i16* null, align 4
73 @b = global i32 0, align 4
75 ; CHECK-LABEL: constexpr
76 ; CHECK: uxth
77 define i32 @constexpr() {
78 entry:
79   store i32 ptrtoint (i32* @b to i32), i32* @b, align 4
80   %0 = load i16*, i16** @a, align 4
81   %1 = load i16, i16* %0, align 2
82   %or = or i16 %1, ptrtoint (i32* @b to i16)
83   store i16 %or, i16* %0, align 2
84   %cmp = icmp ne i16 %or, 4
85   %conv3 = zext i1 %cmp to i32
86   %call = tail call i32 bitcast (i32 (...)* @e to i32 (i32)*)(i32 %conv3) #2
87   ret i32 undef
90 ; The call to safe_lshift_func takes two parameters, but they're the same value
91 ; just one is zext. We do support zext now, so the transformation should
92 ; trigger and we don't want see uxtb here.
93 ; CHECK-LABEL: call_zext_i8_i32
94 ; CHECK-NOT: uxt
95 define fastcc i32 @call_zext_i8_i32(i32 %p_45, i8 zeroext %p_46) {
96 for.cond8.preheader:
97   %call217 = call fastcc zeroext i8 @safe_mul_func_uint8_t_u_u(i8 zeroext undef)
98   %tobool219 = icmp eq i8 %call217, 0
99   br i1 %tobool219, label %for.end411, label %for.cond273.preheader
101 for.cond273.preheader:                            ; preds = %for.cond8.preheader
102   %call217.lcssa = phi i8 [ %call217, %for.cond8.preheader ]
103   %conv218.le = zext i8 %call217.lcssa to i32
104   %call346 = call fastcc zeroext i8 @safe_lshift_func(i8 zeroext %call217.lcssa, i32 %conv218.le)
105   unreachable
107 for.end411:                                       ; preds = %for.cond8.preheader
108   %call452 = call fastcc i64 @safe_sub_func_int64_t_s_s(i64 undef, i64 4)
109   unreachable
112 %struct.anon = type { i32 }
114 @g_57 = hidden local_unnamed_addr global %struct.anon zeroinitializer, align 4
115 @g_893 = hidden local_unnamed_addr global %struct.anon zeroinitializer, align 4
116 @g_82 = hidden local_unnamed_addr global i32 0, align 4
118 ; Test that the transform bails on finding %conv4, a trunc
119 ; CHECK-LABEL: call_return_pointer
120 ; CHECK: sxth
121 ; CHECK: uxt
122 define hidden i32 @call_return_pointer(i8 zeroext %p_13) local_unnamed_addr #0 {
123 entry:
124   %conv1 = zext i8 %p_13 to i16
125   %call = tail call i16** @func_62(i8 zeroext undef, i32 undef, i16 signext %conv1, i32* undef)
126   %0 = load i32, i32* getelementptr inbounds (%struct.anon, %struct.anon* @g_893, i32 0, i32 0), align 4
127   %conv2 = trunc i32 %0 to i16
128   br label %for.cond
130 for.cond:                                         ; preds = %for.cond.backedge, %entry
131   %p_13.addr.0 = phi i8 [ %p_13, %entry ], [ %p_13.addr.0.be, %for.cond.backedge ]
132   %tobool = icmp eq i8 %p_13.addr.0, 0
133   br i1 %tobool, label %for.cond.backedge, label %if.then
135 for.cond.backedge:                                ; preds = %for.cond, %if.then
136   %p_13.addr.0.be = phi i8 [ %conv4, %if.then ], [ 0, %for.cond ]
137   br label %for.cond
139 if.then:                                          ; preds = %for.cond
140   %call3 = tail call fastcc signext i16 @safe_sub_func_int16_t_s_s(i16 signext %conv2)
141   %conv4 = trunc i16 %call3 to i8
142   br label %for.cond.backedge
145 ; Check that d.sroa.0.0.be is promoted passed directly into the tail call.
146 ; CHECK-LABEL: check_zext_phi_call_arg
147 ; CHECK-NOT: uxt
148 define i32 @check_zext_phi_call_arg() {
149 entry:
150   br label %for.cond
152 for.cond:                                         ; preds = %for.cond.backedge, %entry
153   %d.sroa.0.0 = phi i16 [ 30, %entry ], [ %d.sroa.0.0.be, %for.cond.backedge ]
154   %tobool = icmp eq i16 %d.sroa.0.0, 0
155   br i1 %tobool, label %for.cond.backedge, label %if.then
157 for.cond.backedge:                                ; preds = %for.cond, %if.then
158   %d.sroa.0.0.be = phi i16 [ %call, %if.then ], [ 0, %for.cond ]
159   br label %for.cond
161 if.then:                                          ; preds = %for.cond
162   %d.sroa.0.0.insert.ext = zext i16 %d.sroa.0.0 to i32
163   %call = tail call zeroext i16 bitcast (i16 (...)* @f to i16 (i32)*)(i32 %d.sroa.0.0.insert.ext) #2
164   br label %for.cond.backedge
167 %struct.atomic_flag = type { i8 }
169 ; CHECK-LABEL: atomic_flag_test_and_set
170 ; CHECK-NOT: uxt
171 define zeroext i1 @atomic_flag_test_and_set(%struct.atomic_flag* %object) {
172 entry:
173   %_Value = getelementptr inbounds %struct.atomic_flag, %struct.atomic_flag* %object, i32 0, i32 0
174   %call = tail call arm_aapcscc zeroext i8 @__atomic_exchange_1(i8* %_Value, i8 zeroext 1, i32 5) #1
175   %0 = and i8 %call, 1
176   %tobool = icmp ne i8 %0, 0
177   ret i1 %tobool
180 ; CHECK-LABEL: i1_zeroext_call
181 ; CHECK: uxt
182 define i1 @i1_zeroext_call(i16* %ts, i32 %a, i16* %b, i8* %c) {
183 entry:
184   %0 = load i16, i16* %ts, align 2
185   %conv.i860 = trunc i32 %a to i16
186   store i16 %conv.i860, i16* %b, align 2
187   %call.i848 = call zeroext i1 @i1_zeroext(i8* %c, i32 64, i16 zeroext %conv.i860)
188   br i1 %call.i848, label %if.then223, label %if.else227
190 if.then223:
191   %cmp235 = icmp eq i16 %0, %conv.i860
192   br label %exit
194 if.else227:
195   %cmp236 = icmp ult i16 %0, %conv.i860
196   br label %exit
198 exit:
199   %retval = phi i1 [ %cmp235, %if.then223 ], [ %cmp236, %if.else227 ]
200   ret i1 %retval
203 ; CHECK-LABEL: promote_arg_pass_to_call
204 ; CHECK: uxtb
205 define i16 @promote_arg_pass_to_call(i16 zeroext %arg1, i16 zeroext %arg2) {
206   %conv = add nuw i16 %arg1, 15
207   %mul = mul nuw nsw i16 %conv, 3
208   %cmp = icmp ult i16 %mul, %arg2
209   %trunc = trunc i16 %arg1 to i8
210   %res = call zeroext i16 @dummy4(i1 %cmp, i8 %trunc, i16 %arg1)
211   ret i16 %res
215 declare i32 @assert(...)
216 declare i8 @dummy_i8(i8)
217 declare i8 @dummy2(i8*, i8, i8)
218 declare i16 @dummy3(i16)
219 declare i16 @dummy4(i1, i8, i16)
221 declare dso_local i32 @e(...) local_unnamed_addr #1
222 declare dso_local zeroext i16 @f(...) local_unnamed_addr #1
223 declare dso_local arm_aapcscc i8 @__atomic_exchange_1(i8*, i8, i32) local_unnamed_addr
225 declare noalias i16** @func_62(i8 zeroext %p_63, i32 %p_64, i16 signext %p_65, i32* nocapture readnone %p_66)
226 declare fastcc signext i16 @safe_sub_func_int16_t_s_s(i16 signext %si2)
227 declare dso_local fastcc i64 @safe_sub_func_int64_t_s_s(i64, i64)
228 declare dso_local fastcc zeroext i8 @safe_lshift_func(i8 zeroext, i32)
229 declare dso_local fastcc zeroext i8 @safe_mul_func_uint8_t_u_u(i8 returned zeroext)
230 declare i1 @i1_zeroext(i8*, i32, i16 zeroext)