Home | History | Annotate | Download | only in RISCV
      1 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
      2 ; RUN: llc -mtriple=riscv32  < %s | FileCheck  %s
      3 
      4 %struct.S = type { [40 x i32], i32, i32, i32, [4100 x i32], i32, i32, i32 }
      5 @s = common dso_local global %struct.S zeroinitializer, align 4
      6 @foo = global [6 x i16] [i16 1, i16 2, i16 3, i16 4, i16 5, i16 0], align 2
      7 @g = global [1048576 x i8] zeroinitializer, align 1
      8 
      9 
     10 define dso_local void @multiple_stores() local_unnamed_addr {
     11 ; CHECK-LABEL: multiple_stores:
     12 ; CHECK:       # %bb.0: # %entry
     13 ; CHECK-NEXT:    lui a0, %hi(s)
     14 ; CHECK-NEXT:    addi a0, a0, %lo(s)
     15 ; CHECK-NEXT:    addi a1, zero, 20
     16 ; CHECK-NEXT:    sw a1, 164(a0)
     17 ; CHECK-NEXT:    addi a1, zero, 10
     18 ; CHECK-NEXT:    sw a1, 160(a0)
     19 ; CHECK-NEXT:    ret
     20 entry:
     21   store i32 10, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1), align 4
     22   store i32 20, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 2), align 4
     23   ret void
     24 }
     25 
     26 define dso_local void @control_flow_with_mem_access() local_unnamed_addr #0 {
     27 ; CHECK-LABEL: control_flow_with_mem_access:
     28 ; CHECK:       # %bb.0: # %entry
     29 ; CHECK-NEXT:    lui a0, %hi(s)
     30 ; CHECK-NEXT:    addi a0, a0, %lo(s)
     31 ; CHECK-NEXT:    lw a1, 164(a0)
     32 ; CHECK-NEXT:    addi a2, zero, 1
     33 ; CHECK-NEXT:    blt a1, a2, .LBB1_2
     34 ; CHECK-NEXT:  # %bb.1: # %if.then
     35 ; CHECK-NEXT:    addi a1, zero, 10
     36 ; CHECK-NEXT:    sw a1, 160(a0)
     37 ; CHECK-NEXT:  .LBB1_2: # %if.end
     38 ; CHECK-NEXT:    ret
     39 entry:
     40   %0 = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 2), align 4
     41   %cmp = icmp sgt i32 %0, 0
     42   br i1 %cmp, label %if.then, label %if.end
     43 
     44 if.then:                                          ; preds = %entry
     45   store i32 10, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1), align 4
     46   br label %if.end
     47 
     48 if.end:                                           ; preds = %if.then, %entry
     49   ret void
     50 }
     51 
     52 ; This test checks that the offset is reconstructed correctly when
     53 ; "addi" of the big offset has a negative immediate.
     54 ; without peephole this generates:
     55 ; lui  a1, %hi(g)
     56 ; addi a1, a0, %lo(g)
     57 ; lui  a0, 18     ---> offset
     58 ; addi a0, a0, -160
     59 ; add  a0, a0, a1  ---> base + offset.
     60 define i8* @big_offset_neg_addi() {
     61 ; CHECK-LABEL: big_offset_neg_addi:
     62 ; CHECK:       # %bb.0:
     63 ; CHECK-NEXT:    lui a0, %hi(g+73568)
     64 ; CHECK-NEXT:    addi a0, a0, %lo(g+73568)
     65 ; CHECK-NEXT:    ret
     66   ret i8* getelementptr inbounds ([1048576 x i8], [1048576 x i8]* @g, i32 0, i32 73568)
     67 }
     68 
     69 ; This test checks for the case where the offset is only an LUI.
     70 ; without peephole this generates:
     71 ; lui  a0, %hi(g)
     72 ; addi a0, a0, %lo(g)
     73 ; lui  a1, 128     ---> offset
     74 ; add  a0, a0, a1  ---> base + offset.
     75 define i8* @big_offset_lui_tail() {
     76 ; CHECK-LABEL: big_offset_lui_tail:
     77 ; CHECK:       # %bb.0:
     78 ; CHECK-NEXT:    lui a0, %hi(g+524288)
     79 ; CHECK-NEXT:    addi a0, a0, %lo(g+524288)
     80 ; CHECK-NEXT:    ret
     81   ret i8* getelementptr inbounds ([1048576 x i8], [1048576 x i8]* @g, i32 0, i32 524288)
     82 }
     83 
     84 define dso_local i32* @big_offset_one_use() local_unnamed_addr {
     85 ; CHECK-LABEL: big_offset_one_use:
     86 ; CHECK:       # %bb.0: # %entry
     87 ; CHECK-NEXT:    lui a0, %hi(s+16572)
     88 ; CHECK-NEXT:    addi a0, a0, %lo(s+16572)
     89 ; CHECK-NEXT:    ret
     90 entry:
     91   ret i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 5)
     92 }
     93 
     94 define dso_local i32* @small_offset_one_use() local_unnamed_addr {
     95 ; CHECK-LABEL: small_offset_one_use:
     96 ; CHECK:       # %bb.0: # %entry
     97 ; CHECK-NEXT:    lui a0, %hi(s+160)
     98 ; CHECK-NEXT:    addi a0, a0, %lo(s+160)
     99 ; CHECK-NEXT:    ret
    100 entry:
    101   ret i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1)
    102 }
    103 
    104 ; Function Attrs: norecurse nounwind optsize readonly
    105 define dso_local i32* @control_flow_no_mem(i32 %n) local_unnamed_addr #1 {
    106 ; CHECK-LABEL: control_flow_no_mem:
    107 ; CHECK:       # %bb.0: # %entry
    108 ; CHECK-NEXT:    lui a0, %hi(s)
    109 ; CHECK-NEXT:    addi a0, a0, %lo(s)
    110 ; CHECK-NEXT:    lw a1, 164(a0)
    111 ; CHECK-NEXT:    beqz a1, .LBB6_2
    112 ; CHECK-NEXT:  # %bb.1: # %if.end
    113 ; CHECK-NEXT:    addi a0, a0, 168
    114 ; CHECK-NEXT:    ret
    115 ; CHECK-NEXT:  .LBB6_2: # %if.then
    116 ; CHECK-NEXT:    addi a0, a0, 160
    117 ; CHECK-NEXT:    ret
    118 entry:
    119   %0 = load i32, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 2), align 4
    120   %cmp = icmp eq i32 %0, 0
    121   br i1 %cmp, label %if.then, label %if.end
    122 if.then:                                          ; preds = %entry
    123   ret i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1)
    124 if.end:                                           ; preds = %if.then, %entry
    125   ret i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 3)
    126 }
    127 
    128 define dso_local i32 @load_half() nounwind {
    129 ; CHECK-LABEL: load_half:
    130 ; CHECK:       # %bb.0: # %entry
    131 ; CHECK-NEXT:    addi sp, sp, -16
    132 ; CHECK-NEXT:    sw ra, 12(sp)
    133 ; CHECK-NEXT:    lui a0, %hi(foo+8)
    134 ; CHECK-NEXT:    lhu a0, %lo(foo+8)(a0)
    135 ; CHECK-NEXT:    addi a1, zero, 140
    136 ; CHECK-NEXT:    bne a0, a1, .LBB7_2
    137 ; CHECK-NEXT:  # %bb.1: # %if.end
    138 ; CHECK-NEXT:    mv a0, zero
    139 ; CHECK-NEXT:    lw ra, 12(sp)
    140 ; CHECK-NEXT:    addi sp, sp, 16
    141 ; CHECK-NEXT:    ret
    142 ; CHECK-NEXT:  .LBB7_2: # %if.then
    143 ; CHECK-NEXT:    call abort
    144 entry:
    145   %0 = load i16, i16* getelementptr inbounds ([6 x i16], [6 x i16]* @foo, i32 0, i32 4), align 2
    146   %cmp = icmp eq i16 %0, 140
    147   br i1 %cmp, label %if.end, label %if.then
    148 
    149 if.then:
    150   tail call void @abort()
    151   unreachable
    152 
    153 if.end:
    154   ret i32 0
    155 }
    156 
    157 declare void @abort()
    158 
    159 define dso_local void @one_store() local_unnamed_addr {
    160 ; CHECK-LABEL: one_store:
    161 ; CHECK:       # %bb.0: # %entry
    162 ; CHECK-NEXT:    lui a0, %hi(s+160)
    163 ; CHECK-NEXT:    addi a1, zero, 10
    164 ; CHECK-NEXT:    sw a1, %lo(s+160)(a0)
    165 ; CHECK-NEXT:    ret
    166 entry:
    167   store i32 10, i32* getelementptr inbounds (%struct.S, %struct.S* @s, i32 0, i32 1), align 4
    168   ret void
    169 }
    170