[InstCombine] Signed saturation patterns
[llvm-complete.git] / test / CodeGen / ARM / CGP / arm-cgp-phis-ret.ll
blob9b07a80e9a1c1452ba6ba1ffdf0a51448e195339
1 ; RUN: llc -mtriple=thumbv7m -arm-disable-cgp=false %s -o - | FileCheck %s --check-prefix=CHECK-COMMON
2 ; RUN: llc -mtriple=thumbv8m.main -arm-disable-cgp=false %s -o - | FileCheck %s --check-prefix=CHECK-COMMON
3 ; RUN: llc -mtriple=thumbv8m.main -arm-disable-cgp=false -arm-enable-scalar-dsp=true -mcpu=cortex-m33 %s -o - | FileCheck %s --check-prefix=CHECK-COMMON
4 ; RUN: llc -mtriple=thumbv7em %s -arm-disable-cgp=false -arm-enable-scalar-dsp=true -arm-enable-scalar-dsp-imms=true -o - | FileCheck %s --check-prefix=CHECK-COMMON
6 ; Test that ARMCodeGenPrepare can handle:
7 ; - loops
8 ; - call operands
9 ; - call return values
10 ; - ret instructions
11 ; We use nuw on the arithmetic instructions to avoid complications.
13 ; Check that the arguments are extended but then nothing else is.
14 ; This also ensures that the pass can handle loops.
15 ; CHECK-COMMON-LABEL: phi_feeding_phi_args
16 ; CHECK-COMMON: uxtb
17 ; CHECK-COMMON: uxtb
18 ; CHECK-NOT: uxtb
19 define void @phi_feeding_phi_args(i8 %a, i8 %b) {
20 entry:
21   %0 = icmp ugt i8 %a, %b
22   br i1 %0, label %preheader, label %empty
24 empty:
25   br label %preheader
27 preheader:
28   %1 = phi i8 [ %a, %entry ], [ %b, %empty ]
29   br label %loop
31 loop:
32   %val = phi i8 [ %1, %preheader ], [ %inc2, %if.end ]
33   %cmp = icmp ult i8 %val, 254
34   br i1 %cmp, label %if.then, label %if.else
36 if.then:
37   %inc = sub nuw i8 %val, 2
38   br label %if.end
40 if.else:
41   %inc1 = shl nuw i8 %val, 1
42   br label %if.end
44 if.end:
45   %inc2 = phi i8 [ %inc, %if.then], [ %inc1, %if.else ]
46   %cmp1 = icmp eq i8 %inc2, 255
47   br i1 %cmp1, label %exit, label %loop
49 exit:
50   ret void
53 ; Same as above, but as the args are zeroext, we shouldn't see any uxts.
54 ; CHECK-COMMON-LABEL: phi_feeding_phi_zeroext_args
55 ; CHECK-COMMON-NOT: uxt
56 define void @phi_feeding_phi_zeroext_args(i8 zeroext %a, i8 zeroext %b) {
57 entry:
58   %0 = icmp ugt i8 %a, %b
59   br i1 %0, label %preheader, label %empty
61 empty:
62   br label %preheader
64 preheader:
65   %1 = phi i8 [ %a, %entry ], [ %b, %empty ]
66   br label %loop
68 loop:
69   %val = phi i8 [ %1, %preheader ], [ %inc2, %if.end ]
70   %cmp = icmp ult i8 %val, 254
71   br i1 %cmp, label %if.then, label %if.else
73 if.then:
74   %inc = sub nuw i8 %val, 2
75   br label %if.end
77 if.else:
78   %inc1 = shl nuw i8 %val, 1
79   br label %if.end
81 if.end:
82   %inc2 = phi i8 [ %inc, %if.then], [ %inc1, %if.else ]
83   %cmp1 = icmp eq i8 %inc2, 255
84   br i1 %cmp1, label %exit, label %loop
86 exit:
87   ret void
90 ; Just check that phis also work with i16s.
91 ; CHECK-COMMON-LABEL: phi_i16:
92 ; CHECK-COMMON-NOT:   uxt
93 define void @phi_i16() {
94 entry:
95   br label %loop
97 loop:
98   %val = phi i16 [ 0, %entry ], [ %inc2, %if.end ]
99   %cmp = icmp ult i16 %val, 128
100   br i1 %cmp, label %if.then, label %if.else
102 if.then:
103   %inc = add nuw i16 %val, 2
104   br label %if.end
106 if.else:
107   %inc1 = add nuw i16 %val, 1
108   br label %if.end
110 if.end:
111   %inc2 = phi i16 [ %inc, %if.then], [ %inc1, %if.else ]
112   %cmp1 = icmp ult i16 %inc2, 253
113   br i1 %cmp1, label %loop, label %exit
115 exit:
116   ret void
119 ; CHECK-COMMON-LABEL: ret_i8
120 ; CHECK-COMMON-NOT:   uxt
121 define i8 @ret_i8() {
122 entry:
123   br label %loop
125 loop:
126   %val = phi i8 [ 0, %entry ], [ %inc2, %if.end ]
127   %cmp = icmp ult i8 %val, 128
128   br i1 %cmp, label %if.then, label %if.else
130 if.then:
131   %inc = add nuw i8 %val, 2
132   br label %if.end
134 if.else:
135   %inc1 = add nuw i8 %val, 1
136   br label %if.end
138 if.end:
139   %inc2 = phi i8 [ %inc, %if.then], [ %inc1, %if.else ]
140   %cmp1 = icmp ult i8 %inc2, 253
141   br i1 %cmp1, label %exit, label %loop
143 exit:
144   ret i8 %inc2
147 ; CHECK-COMMON-LABEL: phi_multiple_undefs
148 ; CHECK-COMMON-NOT:   uxt
149 define i16 @phi_multiple_undefs(i16 zeroext %arg) {
150 entry:
151   br label %loop
153 loop:
154   %val = phi i16 [ undef, %entry ], [ %inc2, %if.end ]
155   %cmp = icmp ult i16 %val, 128
156   br i1 %cmp, label %if.then, label %if.else
158 if.then:
159   %inc = add nuw i16 %val, 2
160   br label %if.end
162 if.else:
163   %inc1 = add nuw i16 %val, 1
164   br label %if.end
166 if.end:
167   %inc2 = phi i16 [ %inc, %if.then], [ %inc1, %if.else ]
168   %unrelated = phi i16 [ undef, %if.then ], [ %arg, %if.else ]
169   %cmp1 = icmp ult i16 %inc2, 253
170   br i1 %cmp1, label %loop, label %exit
172 exit:
173   ret i16 %unrelated
176 ; CHECK-COMMON-LABEL: promote_arg_return
177 ; CHECK-COMMON-NOT: uxt
178 ; CHECK-COMMON: strb
179 define i16 @promote_arg_return(i16 zeroext %arg1, i16 zeroext %arg2, i8* %res) {
180   %add = add nuw i16 %arg1, 15
181   %mul = mul nuw nsw i16 %add, 3
182   %cmp = icmp ult i16 %mul, %arg2
183   %conv = zext i1 %cmp to i8
184   store i8 %conv, i8* %res
185   ret i16 %arg1
188 ; CHECK-COMMON-LABEL: signext_bitcast_phi_select
189 ; CHECK: uxth [[UXT:r[0-9]+]], r0
190 ; CHECK: sxth [[SXT:r[0-9]+]], [[UXT]]
191 ; CHECK: cmp [[SXT]],
192 ; CHECK-NOT: xth
193 define i16 @signext_bitcast_phi_select(i16 signext %start, i16* %in) {
194 entry:
195   %const = bitcast i16 -1 to i16
196   br label %for.body
198 for.body:
199   %idx = phi i16 [ %select, %if.else ], [ %start, %entry ]
200   %cmp.i = icmp sgt i16 %idx, %const
201   br i1 %cmp.i, label %exit, label %if.then
203 if.then:
204   %idx.next = getelementptr i16, i16* %in, i16 %idx
205   %ld = load i16, i16* %idx.next, align 2
206   %cmp1.i = icmp eq i16 %ld, %idx
207   br i1 %cmp1.i, label %exit, label %if.else
209 if.else:
210   %lobit = lshr i16 %idx, 15
211   %lobit.not = xor i16 %lobit, 1
212   %select = add nuw i16 %lobit.not, %idx
213   br label %for.body
215 exit:
216   %res = phi i16 [ %ld, %if.then ], [ 0, %for.body ]
217   ret i16 %res