blob: 65588b84f7ccc6cab0e80c2759d33f919658f380 [file] [log] [blame]
Sam Parker7def86b2018-08-15 07:52:35 +00001; RUN: llc -mtriple=thumbv7m -arm-disable-cgp=false %s -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-NODSP
2; RUN: llc -mtriple=thumbv8m.main -arm-disable-cgp=false %s -o - | FileCheck %s --check-prefix=CHECK-COMMON --check-prefix=CHECK-NODSP
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 --check-prefix=CHECK-DSP
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 --check-prefix=CHECK-DSP-IMM
5
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.
12
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
19define void @phi_feeding_phi_args(i8 %a, i8 %b) {
20entry:
21 %0 = icmp ugt i8 %a, %b
22 br i1 %0, label %preheader, label %empty
23
24empty:
25 br label %preheader
26
27preheader:
28 %1 = phi i8 [ %a, %entry ], [ %b, %empty ]
29 br label %loop
30
31loop:
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
35
36if.then:
37 %inc = sub nuw i8 %val, 2
38 br label %if.end
39
40if.else:
41 %inc1 = shl nuw i8 %val, 1
42 br label %if.end
43
44if.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
48
49exit:
50 ret void
51}
52
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
56define void @phi_feeding_phi_zeroext_args(i8 zeroext %a, i8 zeroext %b) {
57entry:
58 %0 = icmp ugt i8 %a, %b
59 br i1 %0, label %preheader, label %empty
60
61empty:
62 br label %preheader
63
64preheader:
65 %1 = phi i8 [ %a, %entry ], [ %b, %empty ]
66 br label %loop
67
68loop:
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
72
73if.then:
74 %inc = sub nuw i8 %val, 2
75 br label %if.end
76
77if.else:
78 %inc1 = shl nuw i8 %val, 1
79 br label %if.end
80
81if.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
85
86exit:
87 ret void
88}
89
90; Just check that phis also work with i16s.
91; CHECK-COMMON-LABEL: phi_i16:
92; CHECK-COMMON-NOT: uxt
93define void @phi_i16() {
94entry:
95 br label %loop
96
97loop:
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
101
102if.then:
103 %inc = add nuw i16 %val, 2
104 br label %if.end
105
106if.else:
107 %inc1 = add nuw i16 %val, 1
108 br label %if.end
109
110if.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
114
115exit:
116 ret void
117}
118
119; CHECK-COMMON-LABEL: ret_i8
120; CHECK-COMMON-NOT: uxt
121define i8 @ret_i8() {
122entry:
123 br label %loop
124
125loop:
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
129
130if.then:
131 %inc = add nuw i8 %val, 2
132 br label %if.end
133
134if.else:
135 %inc1 = add nuw i8 %val, 1
136 br label %if.end
137
138if.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
142
143exit:
144 ret i8 %inc2
145}
146
147; CHECK-COMMON-LABEL: phi_multiple_undefs
148; CHECK-COMMON-NOT: uxt
149define i16 @phi_multiple_undefs(i16 zeroext %arg) {
150entry:
151 br label %loop
152
153loop:
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
157
158if.then:
159 %inc = add nuw i16 %val, 2
160 br label %if.end
161
162if.else:
163 %inc1 = add nuw i16 %val, 1
164 br label %if.end
165
166if.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
171
172exit:
173 ret i16 %unrelated
174}