Home | History | Annotate | Download | only in ARM
      1 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=ARM
      2 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=armv7-linux-gnueabi -verify-machineinstrs | FileCheck %s --check-prefix=ARM
      3 ; RUN: llc < %s -O0 -fast-isel-abort=1 -relocation-model=dynamic-no-pic -mtriple=thumbv7-apple-ios -verify-machineinstrs | FileCheck %s --check-prefix=THUMB
      4 
      5 ; Very basic fast-isel functionality.
      6 define i32 @test0(i32 %a, i32 %b) nounwind {
      7 entry:
      8   %a.addr = alloca i32, align 4
      9   %b.addr = alloca i32, align 4
     10   store i32 %a, i32* %a.addr
     11   store i32 %b, i32* %b.addr
     12   %tmp = load i32, i32* %a.addr
     13   %tmp1 = load i32, i32* %b.addr
     14   %add = add nsw i32 %tmp, %tmp1
     15   ret i32 %add
     16 }
     17 
     18 ; Check truncate to bool
     19 define void @test1(i32 %tmp) nounwind {
     20 entry:
     21 %tobool = trunc i32 %tmp to i1
     22 br i1 %tobool, label %if.then, label %if.end
     23 
     24 if.then:                                          ; preds = %entry
     25 call void @test1(i32 0)
     26 br label %if.end
     27 
     28 if.end:                                           ; preds = %if.then, %entry
     29 ret void
     30 ; ARM-LABEL: test1:
     31 ; ARM: tst r0, #1
     32 ; THUMB-LABEL: test1:
     33 ; THUMB: tst.w r0, #1
     34 }
     35 
     36 ; Check some simple operations with immediates
     37 define void @test2(i32 %tmp, i32* %ptr) nounwind {
     38 ; THUMB-LABEL: test2:
     39 ; ARM-LABEL: test2:
     40 
     41 b1:
     42   %a = add i32 %tmp, 4096
     43   store i32 %a, i32* %ptr
     44   br label %b2
     45 
     46 ; THUMB: add.w {{.*}} #4096
     47 ; ARM: add {{.*}} #4096
     48 
     49 b2:
     50   %b = add i32 %tmp, 4095
     51   store i32 %b, i32* %ptr
     52   br label %b3
     53 ; THUMB: addw {{.*}} #4095
     54 ; ARM: movw {{.*}} #4095
     55 ; ARM: add
     56 
     57 b3:
     58   %c = or i32 %tmp, 4
     59   store i32 %c, i32* %ptr
     60   ret void
     61 
     62 ; THUMB: orr {{.*}} #4
     63 ; ARM: orr {{.*}} #4
     64 }
     65 
     66 define void @test3(i32 %tmp, i32* %ptr1, i16* %ptr2, i8* %ptr3) nounwind {
     67 ; THUMB-LABEL: test3:
     68 ; ARM-LABEL: test3:
     69 
     70 bb1:
     71   %a1 = trunc i32 %tmp to i16
     72   %a2 = trunc i16 %a1 to i8
     73   %a3 = trunc i8 %a2 to i1
     74   %a4 = zext i1 %a3 to i8
     75   store i8 %a4, i8* %ptr3
     76   %a5 = zext i8 %a4 to i16
     77   store i16 %a5, i16* %ptr2
     78   %a6 = zext i16 %a5 to i32
     79   store i32 %a6, i32* %ptr1
     80   br label %bb2
     81 
     82 ; THUMB: and
     83 ; THUMB: strb
     84 ; THUMB: and{{.*}}, #255
     85 ; THUMB: strh
     86 ; THUMB: uxth
     87 ; ARM: and
     88 ; ARM: strb
     89 ; ARM: and{{.*}}, #255
     90 ; ARM: strh
     91 ; ARM: uxth
     92 
     93 bb2:
     94   %b1 = trunc i32 %tmp to i16
     95   %b2 = trunc i16 %b1 to i8
     96   store i8 %b2, i8* %ptr3
     97   %b3 = sext i8 %b2 to i16
     98   store i16 %b3, i16* %ptr2
     99   %b4 = sext i16 %b3 to i32
    100   store i32 %b4, i32* %ptr1
    101   br label %bb3
    102 
    103 ; THUMB: strb
    104 ; THUMB: sxtb
    105 ; THUMB: strh
    106 ; THUMB: sxth
    107 ; ARM: strb
    108 ; ARM: sxtb
    109 ; ARM: strh
    110 ; ARM: sxth
    111 
    112 bb3:
    113   %c1 = load i8, i8* %ptr3
    114   %c2 = load i16, i16* %ptr2
    115   %c3 = load i32, i32* %ptr1
    116   %c4 = zext i8 %c1 to i32
    117   %c5 = sext i16 %c2 to i32
    118   %c6 = add i32 %c4, %c5
    119   %c7 = sub i32 %c3, %c6
    120   store i32 %c7, i32* %ptr1
    121   ret void
    122 
    123 ; THUMB: ldrb
    124 ; THUMB: ldrh
    125 ; THUMB: and{{.*}}, #255
    126 ; THUMB: sxth
    127 ; THUMB: add
    128 ; THUMB: sub
    129 ; ARM: ldrb
    130 ; ARM: ldrh
    131 ; ARM: and{{.*}}, #255
    132 ; ARM: sxth
    133 ; ARM: add
    134 ; ARM: sub
    135 }
    136 
    137 ; Check loads/stores with globals
    138 @test4g = external global i32
    139 
    140 define void @test4() {
    141   %a = load i32, i32* @test4g
    142   %b = add i32 %a, 1
    143   store i32 %b, i32* @test4g
    144   ret void
    145 
    146 
    147 ; Note that relocations are either movw/movt or constant pool
    148 ; loads. Different platforms will select different approaches.
    149 
    150 ; THUMB: {{(movw r0, :lower16:L_test4g\$non_lazy_ptr)|(ldr.n r0, .LCPI)}}
    151 ; THUMB: {{(movt r0, :upper16:L_test4g\$non_lazy_ptr)?}}
    152 ; THUMB: ldr r0, [r0]
    153 ; THUMB: ldr r1, [r0]
    154 ; THUMB: adds r1, #1
    155 ; THUMB: str r1, [r0]
    156 
    157 ; ARM: {{(movw r0, :lower16:L_test4g\$non_lazy_ptr)|(ldr r0, .LCPI)}}
    158 ; ARM: {{(movt r0, :upper16:L_test4g\$non_lazy_ptr)?}}
    159 ; ARM: ldr r0, [r0]
    160 ; ARM: ldr r1, [r0]
    161 ; ARM: add r1, r1, #1
    162 ; ARM: str r1, [r0]
    163 }
    164 
    165 ; ARM: @urem_fold
    166 ; THUMB: @urem_fold
    167 ; ARM: and r0, r0, #31
    168 ; THUMB: and r0, r0, #31
    169 define i32 @urem_fold(i32 %a) nounwind {
    170   %rem = urem i32 %a, 32
    171   ret i32 %rem
    172 }
    173 
    174 define i32 @trap_intrinsic() noreturn nounwind  {
    175 entry:
    176 ; ARM: @trap_intrinsic
    177 ; THUMB: @trap_intrinsic
    178 ; ARM: trap
    179 ; THUMB: trap
    180   tail call void @llvm.trap( )
    181   unreachable
    182 }
    183 
    184 declare void @llvm.trap() nounwind
    185