Home | History | Annotate | Download | only in llvm2ice_tests
      1 ; Assembly test for simple arithmetic operations.
      2 
      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
      6 
      7 ; RUN: %if --need=target_ARM32 \
      8 ; RUN:   --command %p2i --filetype=obj --disassemble --target arm32 \
      9 ; RUN:   -i %s --args -O2 \
     10 ; RUN:   | %if --need=target_ARM32 \
     11 ; RUN:   --command FileCheck --check-prefix ARM32 --check-prefix ARM-OPT2 %s
     12 ; RUN: %if --need=target_ARM32 \
     13 ; RUN:   --command %p2i --filetype=obj --disassemble --target arm32 \
     14 ; RUN:   -i %s --args -O2 --mattr=hwdiv-arm \
     15 ; RUN:   | %if --need=target_ARM32 \
     16 ; RUN:   --command FileCheck --check-prefix ARM32HWDIV %s
     17 ; RUN: %if --need=target_ARM32 \
     18 ; RUN:   --command %p2i --filetype=obj --disassemble --target arm32 \
     19 ; RUN:   -i %s --args -Om1 \
     20 ; RUN:   | %if --need=target_ARM32 \
     21 ; RUN:   --command FileCheck --check-prefix ARM32 --check-prefix ARM32-OPTM1 %s
     22 ;
     23 ; RUN: %if --need=target_MIPS32 --need=allow_dump \
     24 ; RUN:   --command %p2i --filetype=asm --assemble --disassemble --target mips32\
     25 ; RUN:   -i %s --args -O2 \
     26 ; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
     27 ; RUN:   --command FileCheck --check-prefix MIPS32 %s
     28 
     29 ; RUN: %if --need=target_MIPS32 --need=allow_dump \
     30 ; RUN:   --command %p2i --filetype=asm --assemble --disassemble --target mips32\
     31 ; RUN:   -i %s --args -Om1 \
     32 ; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
     33 ; RUN:   --command FileCheck --check-prefix MIPS32 %s
     34 
     35 define internal i32 @Add(i32 %a, i32 %b) {
     36 entry:
     37   %add = add i32 %b, %a
     38   ret i32 %add
     39 }
     40 ; CHECK-LABEL: Add
     41 ; CHECK: add e
     42 ; ARM32-LABEL: Add
     43 ; ARM32: add r
     44 ; MIPS32-LABEL: Add
     45 ; MIPS32: add
     46 
     47 define internal i32 @And(i32 %a, i32 %b) {
     48 entry:
     49   %and = and i32 %b, %a
     50   ret i32 %and
     51 }
     52 ; CHECK-LABEL: And
     53 ; CHECK: and e
     54 ; ARM32-LABEL: And
     55 ; ARM32: and r
     56 ; MIPS32-LABEL: And
     57 ; MIPS32: and
     58 
     59 define internal i32 @Or(i32 %a, i32 %b) {
     60 entry:
     61   %or = or i32 %b, %a
     62   ret i32 %or
     63 }
     64 ; CHECK-LABEL: Or
     65 ; CHECK: or e
     66 ; ARM32-LABEL: Or
     67 ; ARM32: orr r
     68 ; MIPS32-LABEL: Or
     69 ; MIPS32: or
     70 
     71 define internal i32 @Xor(i32 %a, i32 %b) {
     72 entry:
     73   %xor = xor i32 %b, %a
     74   ret i32 %xor
     75 }
     76 ; CHECK-LABEL: Xor
     77 ; CHECK: xor e
     78 ; ARM32-LABEL: Xor
     79 ; ARM32: eor r
     80 ; MIPS32-LABEL: Xor
     81 ; MIPS32: xor
     82 
     83 define internal i32 @Sub(i32 %a, i32 %b) {
     84 entry:
     85   %sub = sub i32 %a, %b
     86   ret i32 %sub
     87 }
     88 ; CHECK-LABEL: Sub
     89 ; CHECK: sub e
     90 ; ARM32-LABEL: Sub
     91 ; ARM32: sub r
     92 ; MIPS32-LABEL: Sub
     93 ; MIPS32: sub
     94 
     95 define internal i32 @Mul(i32 %a, i32 %b) {
     96 entry:
     97   %mul = mul i32 %b, %a
     98   ret i32 %mul
     99 }
    100 ; CHECK-LABEL: Mul
    101 ; CHECK: imul e
    102 ; ARM32-LABEL: Mul
    103 ; ARM32: mul r
    104 ; MIPS32-LABEL: Mul
    105 ; MIPS32: mul
    106 
    107 ; Check for a valid ARM mul instruction where operands have to be registers.
    108 ; On the other hand x86-32 does allow an immediate.
    109 define internal i32 @MulImm(i32 %a, i32 %b) {
    110 entry:
    111   %mul = mul i32 %a, 99
    112   ret i32 %mul
    113 }
    114 ; CHECK-LABEL: MulImm
    115 ; CHECK: imul e{{.*}},e{{.*}},0x63
    116 ; ARM32-LABEL: MulImm
    117 ; ARM32-OPTM1: mov {{.*}}, #99
    118 ; ARM32-OPTM1: mul r{{.*}}, r{{.*}}, r{{.*}}
    119 ; ARM32-OPT2: rsb [[T:r[0-9]+]], [[S:r[0-9]+]], [[S]], lsl #2
    120 ; ARM32-OPT2-DAG: add [[T]], [[T]], [[S]], lsl #7
    121 ; ARM32-OPT2-DAG: sub [[T]], [[T]], [[S]], lsl #5
    122 ; MIPS32-LABEL: MulImm
    123 ; MIPS32: mul
    124 
    125 ; Check for a valid addressing mode in the x86-32 mul instruction when
    126 ; the second source operand is an immediate.
    127 define internal i64 @MulImm64(i64 %a) {
    128 entry:
    129   %mul = mul i64 %a, 99
    130   ret i64 %mul
    131 }
    132 ; NOTE: the lowering is currently a bit inefficient for small 64-bit constants.
    133 ; The top bits of the immediate are 0, but the instructions modeling that
    134 ; multiply by 0 are not eliminated (see expanded 64-bit ARM lowering).
    135 ; CHECK-LABEL: MulImm64
    136 ; CHECK: mov {{.*}},0x63
    137 ; CHECK: mov {{.*}},0x0
    138 ; CHECK-NOT: mul {{[0-9]+}}
    139 ;
    140 ; ARM32-LABEL: MulImm64
    141 ; ARM32: mov {{.*}}, #99
    142 ; ARM32: mov {{.*}}, #0
    143 ; ARM32: mul r
    144 ; ARM32: mla r
    145 ; ARM32: umull r
    146 ; ARM32: add r
    147 
    148 ; MIPS32-LABEL: MulImm64
    149 
    150 define internal i32 @Sdiv(i32 %a, i32 %b) {
    151 entry:
    152   %div = sdiv i32 %a, %b
    153   ret i32 %div
    154 }
    155 ; CHECK-LABEL: Sdiv
    156 ; CHECK: cdq
    157 ; CHECK: idiv e
    158 ;
    159 ; ARM32-LABEL: Sdiv
    160 ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
    161 ; ARM32: bne
    162 ; The following instruction is ".word 0xe7fedef0 = udf #60896 ; 0xede0".
    163 ; ARM32: e7fedef0
    164 ; ARM32: bl {{.*}} __divsi3
    165 ; ARM32HWDIV-LABEL: Sdiv
    166 ; ARM32HWDIV: tst
    167 ; ARM32HWDIV: bne
    168 ; ARM32HWDIV: sdiv
    169 
    170 ; MIPS32-LABEL: Sdiv
    171 ; MIPS32: div zero,{{.*}},[[REG:.*]]
    172 ; MIPS32: teq [[REG]],zero,0x7
    173 ; MIPS32: mflo
    174 
    175 define internal i32 @SdivConst(i32 %a) {
    176 entry:
    177   %div = sdiv i32 %a, 219
    178   ret i32 %div
    179 }
    180 ; CHECK-LABEL: SdivConst
    181 ; CHECK: cdq
    182 ; CHECK: idiv e
    183 ;
    184 ; ARM32-LABEL: SdivConst
    185 ; ARM32-NOT: tst
    186 ; ARM32: bl {{.*}} __divsi3
    187 ; ARM32HWDIV-LABEL: SdivConst
    188 ; ARM32HWDIV-NOT: tst
    189 ; ARM32HWDIV: sdiv
    190 
    191 ; MIPS32-LABEL: SdivConst
    192 ; MIPS32: div zero,{{.*}},[[REG:.*]]
    193 ; MIPS32: teq [[REG]],zero,0x7
    194 ; MIPS32: mflo
    195 
    196 define internal i32 @Srem(i32 %a, i32 %b) {
    197 entry:
    198   %rem = srem i32 %a, %b
    199   ret i32 %rem
    200 }
    201 ; CHECK-LABEL: Srem
    202 ; CHECK: cdq
    203 ; CHECK: idiv e
    204 ;
    205 ; ARM32-LABEL: Srem
    206 ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
    207 ; ARM32: bne
    208 ; ARM32: bl {{.*}} __modsi3
    209 ; ARM32HWDIV-LABEL: Srem
    210 ; ARM32HWDIV: tst
    211 ; ARM32HWDIV: bne
    212 ; ARM32HWDIV: sdiv
    213 ; ARM32HWDIV: mls
    214 
    215 ; MIPS32-LABEL: Srem
    216 ; MIPS32: div zero,{{.*}},[[REG:.*]]
    217 ; MIPS32: teq [[REG]],zero,0x7
    218 ; MIPS32: mfhi
    219 
    220 define internal i32 @Udiv(i32 %a, i32 %b) {
    221 entry:
    222   %div = udiv i32 %a, %b
    223   ret i32 %div
    224 }
    225 ; CHECK-LABEL: Udiv
    226 ; CHECK: div e
    227 ;
    228 ; ARM32-LABEL: Udiv
    229 ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
    230 ; ARM32: bne
    231 ; ARM32: bl {{.*}} __udivsi3
    232 ; ARM32HWDIV-LABEL: Udiv
    233 ; ARM32HWDIV: tst
    234 ; ARM32HWDIV: bne
    235 ; ARM32HWDIV: udiv
    236 
    237 ; MIPS32-LABEL: Udiv
    238 ; MIPS32: divu zero,{{.*}},[[REG:.*]]
    239 ; MIPS32: teq [[REG]],zero,0x7
    240 ; MIPS32: mflo
    241 
    242 define internal i32 @Urem(i32 %a, i32 %b) {
    243 entry:
    244   %rem = urem i32 %a, %b
    245   ret i32 %rem
    246 }
    247 ; CHECK-LABEL: Urem
    248 ; CHECK: div e
    249 ;
    250 ; ARM32-LABEL: Urem
    251 ; ARM32: tst [[DENOM:r.*]], [[DENOM]]
    252 ; ARM32: bne
    253 ; ARM32: bl {{.*}} __umodsi3
    254 ; ARM32HWDIV-LABEL: Urem
    255 ; ARM32HWDIV: tst
    256 ; ARM32HWDIV: bne
    257 ; ARM32HWDIV: udiv
    258 ; ARM32HWDIV: mls
    259 
    260 ; MIPS32-LABEL: Urem
    261 ; MIPS32: divu zero,{{.*}},[[REG:.*]]
    262 ; MIPS32: teq [[REG]],zero,0x7
    263 ; MIPS32: mfhi
    264 
    265 ; The following tests check that shift instructions don't try to use a
    266 ; ConstantRelocatable as an immediate operand.
    267 
    268 @G = internal global [4 x i8] zeroinitializer, align 4
    269 
    270 define internal i32 @ShlReloc(i32 %a) {
    271 entry:
    272   %opnd = ptrtoint [4 x i8]* @G to i32
    273   %result = shl i32 %a, %opnd
    274   ret i32 %result
    275 }
    276 ; CHECK-LABEL: ShlReloc
    277 ; CHECK: shl {{.*}},cl
    278 
    279 ; MIPS32-LABEL: ShlReloc
    280 ; MIPS32: lui [[REG:.*]],{{.*}} R_MIPS_HI16 G
    281 ; MIPS32: addiu [[REG]],[[REG]],{{.*}} R_MIPS_LO16 G
    282 ; MIPS32: sllv {{.*}},{{.*}},[[REG]]
    283 
    284 define internal i32 @LshrReloc(i32 %a) {
    285 entry:
    286   %opnd = ptrtoint [4 x i8]* @G to i32
    287   %result = lshr i32 %a, %opnd
    288   ret i32 %result
    289 }
    290 ; CHECK-LABEL: LshrReloc
    291 ; CHECK: shr {{.*}},cl
    292 
    293 ; MIPS32-LABEL: LshrReloc
    294 ; MIPS32: lui [[REG:.*]],{{.*}} R_MIPS_HI16 G
    295 ; MIPS32: addiu [[REG]],[[REG]],{{.*}} R_MIPS_LO16 G
    296 ; MIPS32: srlv {{.*}},{{.*}},[[REG]]
    297 
    298 define internal i32 @AshrReloc(i32 %a) {
    299 entry:
    300   %opnd = ptrtoint [4 x i8]* @G to i32
    301   %result = ashr i32 %a, %opnd
    302   ret i32 %result
    303 }
    304 ; CHECK-LABEL: AshrReloc
    305 ; CHECK: sar {{.*}},cl
    306 
    307 ; MIPS32-LABEL: AshrReloc
    308 ; MIPS32: lui [[REG:.*]],{{.*}} R_MIPS_HI16 G
    309 ; MIPS32: addiu [[REG]],[[REG]],{{.*}} R_MIPS_LO16 G
    310 ; MIPS32: srav {{.*}},{{.*}},[[REG]]
    311