Home | History | Annotate | Download | only in llvm2ice_tests
      1 ; This is a basic test of the alloca instruction.
      2 
      3 ; RUN: %if --need=target_X8632 --command %p2i --filetype=obj --disassemble \
      4 ; RUN:   --target x8632 -i %s --args -O2 -allow-externally-defined-symbols \
      5 ; RUN:   | %if --need=target_X8632 --command FileCheck %s
      6 
      7 ; RUN: %if --need=target_MIPS32 --need=allow_dump \
      8 ; RUN:   --command %p2i --filetype=asm --assemble --disassemble --target \
      9 ; RUN:   mips32 -i %s --args -O2 -allow-externally-defined-symbols \
     10 ; RUN:   | %if --need=target_MIPS32 --need=allow_dump \
     11 ; RUN:   --command FileCheck --check-prefix MIPS32 %s
     12 
     13 ; Test that a sequence of allocas with less than stack alignment get fused.
     14 define internal void @fused_small_align(i32 %arg) {
     15 entry:
     16   %a1 = alloca i8, i32 8, align 4
     17   %a2 = alloca i8, i32 12, align 4
     18   %a3 = alloca i8, i32 16, align 8
     19   %p1 = bitcast i8* %a1 to i32*
     20   %p2 = bitcast i8* %a2 to i32*
     21   %p3 = bitcast i8* %a3 to i32*
     22   store i32 %arg, i32* %p1, align 1
     23   store i32 %arg, i32* %p2, align 1
     24   store i32 %arg, i32* %p3, align 1
     25   ret void
     26 }
     27 ; CHECK-LABEL: fused_small_align
     28 ; CHECK-NEXT: sub    esp,0x3c
     29 ; CHECK-NEXT: mov    eax,DWORD PTR [esp+0x40]
     30 ; CHECK-NEXT: mov    DWORD PTR [esp+0x10],eax
     31 ; CHECK-NEXT: mov    DWORD PTR [esp+0x18],eax
     32 ; CHECK-NEXT: mov    DWORD PTR [esp],eax
     33 ; CHECK-NEXT: add    esp,0x3c
     34 ; MIPS32-LABEL: fused_small_align
     35 ; MIPS32: 	addiu	sp,sp,{{.*}}
     36 ; MIPS32: 	move	v0,a0
     37 ; MIPS32: 	sw	v0,{{.*}}(sp)
     38 ; MIPS32: 	move	v0,a0
     39 ; MIPS32: 	sw	v0,{{.*}}(sp)
     40 ; MIPS32: 	sw	a0,{{.*}}(sp)
     41 ; MIPS32: 	addiu	sp,sp,{{.*}}
     42 
     43 ; Test that a sequence of allocas with greater than stack alignment get fused.
     44 define internal void @fused_large_align(i32 %arg) {
     45 entry:
     46   %a1 = alloca i8, i32 8, align 32
     47   %a2 = alloca i8, i32 12, align 64
     48   %a3 = alloca i8, i32 16, align 32
     49   %p1 = bitcast i8* %a1 to i32*
     50   %p2 = bitcast i8* %a2 to i32*
     51   %p3 = bitcast i8* %a3 to i32*
     52   store i32 %arg, i32* %p1, align 1
     53   store i32 %arg, i32* %p2, align 1
     54   store i32 %arg, i32* %p3, align 1
     55   ret void
     56 }
     57 ; CHECK-LABEL: fused_large_align
     58 ; CHECK-NEXT: push   ebp
     59 ; CHECK-NEXT: mov    ebp,esp
     60 ; CHECK-NEXT: sub    esp,0xb8
     61 ; CHECK-NEXT: and    esp,0xffffffc0
     62 ; CHECK-NEXT: mov    eax,DWORD PTR [ebp+0x8]
     63 ; CHECK-NEXT: mov    DWORD PTR [esp+0x40],eax
     64 ; CHECK-NEXT: mov    DWORD PTR [esp],eax
     65 ; CHECK-NEXT: mov    DWORD PTR [esp+0x60],eax
     66 ; CHECK-NEXT: mov    esp,ebp
     67 ; CHECK-NEXT: pop    ebp
     68 ; MIPS32-LABEL: fused_large_align
     69 ; MIPS32: 	addiu	sp,sp,{{.*}}
     70 ; MIPS32: 	sw	s8,{{.*}}(sp)
     71 ; MIPS32: 	move	s8,sp
     72 ; MIPS32: 	move	v0,a0
     73 ; MIPS32: 	sw	v0,{{.*}}(sp)
     74 ; MIPS32: 	move	v0,a0
     75 ; MIPS32: 	sw	v0,{{.*}}(sp)
     76 ; MIPS32: 	sw	a0,{{.*}}(sp)
     77 ; MIPS32: 	move	sp,s8
     78 ; MIPS32: 	lw	s8,{{.*}}(sp)
     79 ; MIPS32: 	addiu	sp,sp,{{.*}}
     80 
     81 ; Test that an interior pointer into a rematerializable variable is also
     82 ; rematerializable, and test that it is detected even when the use appears
     83 ; syntactically before the definition.  Test that it is folded into mem
     84 ; operands, and also rematerializable through an lea instruction for direct use.
     85 define internal i32 @fused_derived(i32 %arg) {
     86 entry:
     87   %a1 = alloca i8, i32 128, align 4
     88   %a2 = alloca i8, i32 128, align 4
     89   %a3 = alloca i8, i32 128, align 4
     90   br label %block2
     91 block1:
     92   %a2_i32 = bitcast i8* %a2 to i32*
     93   store i32 %arg, i32* %a2_i32, align 1
     94   store i32 %arg, i32* %derived, align 1
     95   ret i32 %retval
     96 block2:
     97 ; The following are all rematerializable variables deriving from %a2.
     98   %p2 = ptrtoint i8* %a2 to i32
     99   %d = add i32 %p2, 12
    100   %retval = add i32 %p2, 1
    101   %derived = inttoptr i32 %d to i32*
    102   br label %block1
    103 }
    104 ; CHECK-LABEL: fused_derived
    105 ; CHECK-NEXT: sub    esp,0x18c
    106 ; CHECK-NEXT: mov    [[ARG:e..]],DWORD PTR [esp+0x190]
    107 ; CHECK-NEXT: jmp
    108 ; CHECK-NEXT: mov    DWORD PTR [esp+0x80],[[ARG]]
    109 ; CHECK-NEXT: mov    DWORD PTR [esp+0x8c],[[ARG]]
    110 ; CHECK-NEXT: lea    eax,[esp+0x81]
    111 ; CHECK-NEXT: add    esp,0x18c
    112 ; CHECK-NEXT: ret
    113 ; MIPS32-LABEL: fused_derived
    114 ; MIPS32: 	addiu	sp,sp,{{.*}}
    115 ; MIPS32: 	b
    116 ; MIPS32: 	move	v0,a0
    117 ; MIPS32: 	sw	v0,{{.*}}(sp)
    118 ; MIPS32: 	sw	a0,{{.*}}(sp)
    119 ; MIPS32: 	addiu	v0,sp,129
    120 ; MIPS32: 	addiu	sp,sp,{{.*}}
    121 
    122 ; Test that a fixed alloca gets referenced by the frame pointer.
    123 define internal void @fused_small_align_with_dynamic(i32 %arg) {
    124 entry:
    125   %a1 = alloca i8, i32 8, align 16
    126   br label %next
    127 next:
    128   %a2 = alloca i8, i32 12, align 1
    129   %a3 = alloca i8, i32 16, align 1
    130   %p1 = bitcast i8* %a1 to i32*
    131   %p2 = bitcast i8* %a2 to i32*
    132   %p3 = bitcast i8* %a3 to i32*
    133   store i32 %arg, i32* %p1, align 1
    134   store i32 %arg, i32* %p2, align 1
    135   store i32 %arg, i32* %p3, align 1
    136   ret void
    137 }
    138 ; CHECK-LABEL: fused_small_align_with_dynamic
    139 ; CHECK-NEXT: push   ebp
    140 ; CHECK-NEXT: mov    ebp,esp
    141 ; CHECK-NEXT: sub    esp,0x18
    142 ; CHECK-NEXT: mov    eax,DWORD PTR [ebp+0x8]
    143 ; CHECK-NEXT: sub    esp,0x10
    144 ; CHECK-NEXT: mov    ecx,esp
    145 ; CHECK-NEXT: sub    esp,0x10
    146 ; CHECK-NEXT: mov    edx,esp
    147 ; CHECK-NEXT: mov    DWORD PTR [ebp-0x18],eax
    148 ; CHECK-NEXT: mov    DWORD PTR [ecx],eax
    149 ; CHECK-NEXT: mov    DWORD PTR [edx],eax
    150 ; CHECK-NEXT: mov    esp,ebp
    151 ; CHECK-NEXT: pop    ebp
    152 ; MIPS32-LABEL: fused_small_align_with_dynamic
    153 ; MIPS32: 	addiu	sp,sp,{{.*}}
    154 ; MIPS32: 	sw	s8,{{.*}}(sp)
    155 ; MIPS32: 	move	s8,sp
    156 ; MIPS32: 	addiu	v0,sp,0
    157 ; MIPS32: 	addiu	v1,sp,16
    158 ; MIPS32: 	move	a1,a0
    159 ; MIPS32: 	sw	a1,32(s8)
    160 ; MIPS32: 	move	a1,a0
    161 ; MIPS32: 	sw	a1,0(v0)
    162 ; MIPS32: 	sw	a0,0(v1)
    163 ; MIPS32: 	move	sp,s8
    164 ; MIPS32: 	lw	s8,{{.*}}(sp)
    165 ; MIPS32: 	addiu	sp,sp,{{.*}}
    166 
    167 ; Test that a sequence with greater than stack alignment and dynamic size
    168 ; get folded and referenced correctly;
    169 
    170 define internal void @fused_large_align_with_dynamic(i32 %arg) {
    171 entry:
    172   %a1 = alloca i8, i32 8, align 32
    173   %a2 = alloca i8, i32 12, align 32
    174   %a3 = alloca i8, i32 16, align 1
    175   %a4 = alloca i8, i32 16, align 1
    176   br label %next
    177 next:
    178   %a5 = alloca i8, i32 16, align 1
    179   %p1 = bitcast i8* %a1 to i32*
    180   %p2 = bitcast i8* %a2 to i32*
    181   %p3 = bitcast i8* %a3 to i32*
    182   %p4 = bitcast i8* %a4 to i32*
    183   %p5 = bitcast i8* %a5 to i32*
    184   store i32 %arg, i32* %p1, align 1
    185   store i32 %arg, i32* %p2, align 1
    186   store i32 %arg, i32* %p3, align 1
    187   store i32 %arg, i32* %p4, align 1
    188   store i32 %arg, i32* %p5, align 1
    189   ret void
    190 }
    191 ; CHECK-LABEL: fused_large_align_with_dynamic
    192 ; CHECK-NEXT: push   ebx
    193 ; CHECK-NEXT: push   ebp
    194 ; CHECK-NEXT: mov    ebp,esp
    195 ; CHECK-NEXT: sub    esp,0x24
    196 ; CHECK-NEXT: mov    eax,DWORD PTR [ebp+0xc]
    197 ; CHECK-NEXT: and    esp,0xffffffe0
    198 ; CHECK-NEXT: sub    esp,0x40
    199 ; CHECK-NEXT: mov    ecx,esp
    200 ; CHECK-NEXT: mov    edx,ecx
    201 ; CHECK-NEXT: add    ecx,0x20
    202 ; CHECK-NEXT: add    edx,0x0
    203 ; CHECK-NEXT: sub    esp,0x10
    204 ; CHECK-NEXT: mov    ebx,esp
    205 ; CHECK-NEXT: mov    DWORD PTR [edx],eax
    206 ; CHECK-NEXT: mov    DWORD PTR [ecx],eax
    207 ; CHECK-NEXT: mov    DWORD PTR [ebp-0x14],eax
    208 ; CHECK-NEXT: mov    DWORD PTR [ebp-0x24],eax
    209 ; CHECK-NEXT: mov    DWORD PTR [ebx],eax
    210 ; CHECK-NEXT: mov    esp,ebp
    211 ; CHECK-NEXT: pop    ebp
    212 ; MIPS32-LABEL: fused_large_align_with_dynamic
    213 ; MIPS32: 	addiu	sp,sp,{{.*}}
    214 ; MIPS32: 	sw	s8,{{.*}}(sp)
    215 ; MIPS32: 	move	s8,sp
    216 ; MIPS32: 	addiu	v0,sp,0
    217 ; MIPS32: 	addiu	v1,sp,64
    218 ; MIPS32: 	move	a1,v0
    219 ; MIPS32: 	move	a2,a0
    220 ; MIPS32: 	sw	a2,0(a1)
    221 ; MIPS32: 	move	a1,a0
    222 ; MIPS32: 	sw	a1,32(v0)
    223 ; MIPS32: 	move	v0,a0
    224 ; MIPS32: 	sw	v0,80(s8)
    225 ; MIPS32: 	move	v0,a0
    226 ; MIPS32: 	sw	v0,96(s8)
    227 ; MIPS32: 	sw	a0,0(v1)
    228 ; MIPS32: 	move	sp,s8
    229 ; MIPS32: 	lw	s8,{{.*}}(sp)
    230 ; MIPS32: 	addiu	sp,sp,{{.*}}
    231