1 ; Assembly test for simple arithmetic operations.
3 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
4 ; RUN: --target x8632 -i %s --args -O2 \
5 ; RUN: | %if --need=target_X8632 --command FileCheck %s
7 ; TODO(jvoung): Stop skipping unimplemented parts (via --skip-unimplemented)
8 ; once enough infrastructure is in. Also, switch to --filetype=obj
10 ; RUN: %if --need=target_ARM32 --need=allow_dump \
11 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \
12 ; RUN: -i %s --args -O2 --skip-unimplemented \
13 ; RUN: | %if --need=target_ARM32 --need=allow_dump \
14 ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM-OPT2 %s
15 ; RUN: %if --need=target_ARM32 --need=allow_dump \
16 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \
17 ; RUN: -i %s --args -O2 --mattr=hwdiv-arm --skip-unimplemented \
18 ; RUN: | %if --need=target_ARM32 --need=allow_dump \
19 ; RUN: --command FileCheck --check-prefix ARM32HWDIV %s
20 ; RUN: %if --need=target_ARM32 --need=allow_dump \
21 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target arm32 \
22 ; RUN: -i %s --args -Om1 --skip-unimplemented \
23 ; RUN: | %if --need=target_ARM32 --need=allow_dump \
24 ; RUN: --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OPTM1 %s
26 ; RUN: %if --need=target_MIPS32 --need=allow_dump \
27 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\
28 ; RUN: -i %s --args -O2 --skip-unimplemented \
29 ; RUN: | %if --need=target_MIPS32 --need=allow_dump \
30 ; RUN: --command FileCheck --check-prefix MIPS32 %s
32 ; RUN: %if --need=target_MIPS32 --need=allow_dump \
33 ; RUN: --command %p2i --filetype=asm --assemble --disassemble --target mips32\
34 ; RUN: -i %s --args -Om1 --skip-unimplemented \
35 ; RUN: | %if --need=target_MIPS32 --need=allow_dump \
36 ; RUN: --command FileCheck --check-prefix MIPS32 %s
38 define internal i32 @Add(i32 %a, i32 %b) {
50 define internal i32 @And(i32 %a, i32 %b) {
62 define internal i32 @Or(i32 %a, i32 %b) {
74 define internal i32 @Xor(i32 %a, i32 %b) {
86 define internal i32 @Sub(i32 %a, i32 %b) {
98 define internal i32 @Mul(i32 %a, i32 %b) {
100 %mul = mul i32 %b, %a
110 ; Check for a valid ARM mul instruction where operands have to be registers.
111 ; On the other hand x86-32 does allow an immediate.
112 define internal i32 @MulImm(i32 %a, i32 %b) {
114 %mul = mul i32 %a, 99
117 ; CHECK-LABEL: MulImm
118 ; CHECK: imul e{{.*}},e{{.*}},0x63
119 ; ARM32-LABEL: MulImm
120 ; ARM32-OPTM1: mov {{.*}}, #99
121 ; ARM32-OPTM1: mul r{{.*}}, r{{.*}}, r{{.*}}
122 ; ARM32-OPT2: rsb [[T:r[0-9]+]], [[S:r[0-9]+]], [[S]], lsl #2
123 ; ARM32-OPT2-DAG: add [[T]], [[T]], [[S]], lsl #7
124 ; ARM32-OPT2-DAG: sub [[T]], [[T]], [[S]], lsl #5
125 ; MIPS32-LABEL: MulImm
128 ; Check for a valid addressing mode in the x86-32 mul instruction when
129 ; the second source operand is an immediate.
130 define internal i64 @MulImm64(i64 %a) {
132 %mul = mul i64 %a, 99
135 ; NOTE: the lowering is currently a bit inefficient for small 64-bit constants.
136 ; The top bits of the immediate are 0, but the instructions modeling that
137 ; multiply by 0 are not eliminated (see expanded 64-bit ARM lowering).
138 ; CHECK-LABEL: MulImm64
139 ; CHECK: mov {{.*}},0x63
140 ; CHECK: mov {{.*}},0x0
141 ; CHECK-NOT: mul {{[0-9]+}}
143 ; ARM32-LABEL: MulImm64
144 ; ARM32: mov {{.*}}, #99
145 ; ARM32: mov {{.*}}, #0
151 ; MIPS32-LABEL: MulImm64
153 define internal i32 @Sdiv(i32 %a, i32 %b) {
155 %div = sdiv i32 %a, %b
163 ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
165 ; ARM32: .word 0xe7fedef0
166 ; ARM32: {{.*}} bl {{.*}} __divsi3
167 ; ARM32HWDIV-LABEL: Sdiv
174 define internal i32 @SdivConst(i32 %a) {
176 %div = sdiv i32 %a, 219
179 ; CHECK-LABEL: SdivConst
183 ; ARM32-LABEL: SdivConst
185 ; ARM32: bl {{.*}} __divsi3
186 ; ARM32HWDIV-LABEL: SdivConst
187 ; ARM32HWDIV-NOT: tst
190 ; MIPS32-LABEL: SdivConst
192 define internal i32 @Srem(i32 %a, i32 %b) {
194 %rem = srem i32 %a, %b
202 ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
204 ; ARM32: bl {{.*}} __modsi3
205 ; ARM32HWDIV-LABEL: Srem
213 define internal i32 @Udiv(i32 %a, i32 %b) {
215 %div = udiv i32 %a, %b
222 ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
224 ; ARM32: bl {{.*}} __udivsi3
225 ; ARM32HWDIV-LABEL: Udiv
232 define internal i32 @Urem(i32 %a, i32 %b) {
234 %rem = urem i32 %a, %b
241 ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
243 ; ARM32: bl {{.*}} __umodsi3
244 ; ARM32HWDIV-LABEL: Urem
252 ; The following tests check that shift instructions don't try to use a
253 ; ConstantRelocatable as an immediate operand.
255 @G = internal global [4 x i8] zeroinitializer, align 4
257 define internal i32 @ShlReloc(i32 %a) {
259 %opnd = ptrtoint [4 x i8]* @G to i32
260 %result = shl i32 %a, %opnd
263 ; CHECK-LABEL: ShlReloc
264 ; CHECK: shl {{.*}},cl
266 define internal i32 @LshrReloc(i32 %a) {
268 %opnd = ptrtoint [4 x i8]* @G to i32
269 %result = lshr i32 %a, %opnd
272 ; CHECK-LABEL: LshrReloc
273 ; CHECK: shr {{.*}},cl
275 define internal i32 @AshrReloc(i32 %a) {
277 %opnd = ptrtoint [4 x i8]* @G to i32
278 %result = ashr i32 %a, %opnd
281 ; CHECK-LABEL: AshrReloc
282 ; CHECK: sar {{.*}},cl