Home | History | Annotate | Download | only in WebAssembly
      1 ; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
      2 
      3 ; Test folding constant offsets and symbols into load and store addresses under
      4 ; a variety of circumstances.
      5 
      6 target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
      7 target triple = "wasm32-unknown-unknown"
      8 
      9 @g = external global [0 x i32], align 4
     10 
     11 ; CHECK-LABEL: load_test0:
     12 ; CHECK-NEXT: result    i32{{$}}
     13 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
     14 ; CHECK-NEXT: i32.load  $push1=, g+40($pop0){{$}}
     15 ; CHECK-NEXT: return    $pop1{{$}}
     16 define i32 @load_test0() {
     17   %t = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
     18   ret i32 %t
     19 }
     20 
     21 ; CHECK-LABEL: load_test0_noinbounds:
     22 ; CHECK-NEXT: result    i32{{$}}
     23 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
     24 ; CHECK-NEXT: i32.load  $push1=, g+40($pop0){{$}}
     25 ; CHECK-NEXT: return    $pop1{{$}}
     26 define i32 @load_test0_noinbounds() {
     27   %t = load i32, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
     28   ret i32 %t
     29 }
     30 
     31 ; TODO: load_test1 - load_test8 are disabled because folding GA+reg is disabled
     32 ; (there are cases where the value in the reg can be negative).
     33 ; Likewise for stores.
     34 
     35 ; CHECK-LABEL: load_test1:
     36 ; CHECK-NEXT: param     i32{{$}}
     37 ; CHECK-NEXT: result    i32{{$}}
     38 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
     39 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
     40 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
     41 ; CHECK-NEX T: return    $pop2{{$}}
     42 define i32 @load_test1(i32 %n) {
     43   %add = add nsw i32 %n, 10
     44   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
     45   %t = load i32, i32* %arrayidx, align 4
     46   ret i32 %t
     47 }
     48 
     49 ; CHECK-LABEL: load_test2:
     50 ; CHECK-NEXT: param     i32{{$}}
     51 ; CHECK-NEXT: result    i32{{$}}
     52 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
     53 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
     54 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
     55 ; CHECK-NEX T: return    $pop2{{$}}
     56 define i32 @load_test2(i32 %n) {
     57   %add = add nsw i32 10, %n
     58   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
     59   %t = load i32, i32* %arrayidx, align 4
     60   ret i32 %t
     61 }
     62 
     63 ; CHECK-LABEL: load_test3:
     64 ; CHECK-NEXT: param     i32{{$}}
     65 ; CHECK-NEXT: result    i32{{$}}
     66 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
     67 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
     68 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
     69 ; CHECK-NEX T: return    $pop2{{$}}
     70 define i32 @load_test3(i32 %n) {
     71   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
     72   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
     73   %t = load i32, i32* %add.ptr1, align 4
     74   ret i32 %t
     75 }
     76 
     77 ; CHECK-LABEL: load_test4:
     78 ; CHECK-NEXT: param     i32{{$}}
     79 ; CHECK-NEXT: result    i32{{$}}
     80 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
     81 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
     82 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
     83 ; CHECK-NEX T: return    $pop2{{$}}
     84 define i32 @load_test4(i32 %n) {
     85   %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
     86   %t = load i32, i32* %add.ptr, align 4
     87   ret i32 %t
     88 }
     89 
     90 ; CHECK-LABEL: load_test5:
     91 ; CHECK-NEXT: param     i32{{$}}
     92 ; CHECK-NEXT: result    i32{{$}}
     93 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
     94 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
     95 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
     96 ; CHECK-NEX T: return    $pop2{{$}}
     97 define i32 @load_test5(i32 %n) {
     98   %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
     99   %t = load i32, i32* %add.ptr, align 4
    100   ret i32 %t
    101 }
    102 
    103 ; CHECK-LABEL: load_test6:
    104 ; CHECK-NEXT: param     i32{{$}}
    105 ; CHECK-NEXT: result    i32{{$}}
    106 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    107 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
    108 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
    109 ; CHECK-NEX T: return    $pop2{{$}}
    110 define i32 @load_test6(i32 %n) {
    111   %add = add nsw i32 %n, 10
    112   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
    113   %t = load i32, i32* %add.ptr, align 4
    114   ret i32 %t
    115 }
    116 
    117 ; CHECK-LABEL: load_test7:
    118 ; CHECK-NEXT: param     i32{{$}}
    119 ; CHECK-NEXT: result    i32{{$}}
    120 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    121 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
    122 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
    123 ; CHECK-NEX T: return    $pop2{{$}}
    124 define i32 @load_test7(i32 %n) {
    125   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
    126   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
    127   %t = load i32, i32* %add.ptr1, align 4
    128   ret i32 %t
    129 }
    130 
    131 ; CHECK-LABEL: load_test8:
    132 ; CHECK-NEXT: param     i32{{$}}
    133 ; CHECK-NEXT: result    i32{{$}}
    134 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    135 ; CHECK-NEX T: i32.shl   $push1=, $0, $pop0{{$}}
    136 ; CHECK-NEX T: i32.load  $push2=, g+40($pop1){{$}}
    137 ; CHECK-NEX T: return    $pop2{{$}}
    138 define i32 @load_test8(i32 %n) {
    139   %add = add nsw i32 10, %n
    140   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
    141   %t = load i32, i32* %add.ptr, align 4
    142   ret i32 %t
    143 }
    144 
    145 ; CHECK-LABEL: load_test9:
    146 ; CHECK-NEXT: result    i32{{$}}
    147 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
    148 ; CHECK-NEXT: i32.load  $push1=, g-40($pop0){{$}}
    149 ; CHECK-NEXT: return    $pop1{{$}}
    150 define i32 @load_test9() {
    151   %t = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4
    152   ret i32 %t
    153 }
    154 
    155 ; CHECK-LABEL: load_test10:
    156 ; CHECK-NEXT: param     i32{{$}}
    157 ; CHECK-NEXT: result    i32{{$}}
    158 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    159 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    160 ; CHECK-NEXT: i32.const $push2=, g-40{{$}}
    161 ; CHECK-NEXT: i32.add   $push3=, $pop1, $pop2{{$}}
    162 ; CHECK-NEXT: i32.load  $push4=, 0($pop3){{$}}
    163 ; CHECK-NEXT: return    $pop4{{$}}
    164 define i32 @load_test10(i32 %n) {
    165   %add = add nsw i32 %n, -10
    166   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
    167   %t = load i32, i32* %arrayidx, align 4
    168   ret i32 %t
    169 }
    170 
    171 ; CHECK-LABEL: load_test11:
    172 ; CHECK-NEXT: param     i32{{$}}
    173 ; CHECK-NEXT: result    i32{{$}}
    174 ; CHECK-NEXT: i32.load  $push0=, 40($0){{$}}
    175 ; CHECK-NEXT: return    $pop0{{$}}
    176 define i32 @load_test11(i32* %p) {
    177   %arrayidx = getelementptr inbounds i32, i32* %p, i32 10
    178   %t = load i32, i32* %arrayidx, align 4
    179   ret i32 %t
    180 }
    181 
    182 ; CHECK-LABEL: load_test11_noinbounds:
    183 ; CHECK-NEXT: param     i32{{$}}
    184 ; CHECK-NEXT: result    i32{{$}}
    185 ; CHECK-NEXT: i32.const $push0=, 40{{$}}
    186 ; CHECK-NEXT: i32.add   $push1=, $0, $pop0{{$}}
    187 ; CHECK-NEXT: i32.load  $push2=, 0($pop1){{$}}
    188 ; CHECK-NEXT: return    $pop2{{$}}
    189 define i32 @load_test11_noinbounds(i32* %p) {
    190   %arrayidx = getelementptr i32, i32* %p, i32 10
    191   %t = load i32, i32* %arrayidx, align 4
    192   ret i32 %t
    193 }
    194 
    195 ; CHECK-LABEL: load_test12:
    196 ; CHECK-NEXT: param     i32, i32{{$}}
    197 ; CHECK-NEXT: result    i32{{$}}
    198 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    199 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    200 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    201 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    202 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    203 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
    204 ; CHECK-NEXT: return    $pop5{{$}}
    205 define i32 @load_test12(i32* %p, i32 %n) {
    206   %add = add nsw i32 %n, 10
    207   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
    208   %t = load i32, i32* %arrayidx, align 4
    209   ret i32 %t
    210 }
    211 
    212 ; CHECK-LABEL: load_test13:
    213 ; CHECK-NEXT: param     i32, i32{{$}}
    214 ; CHECK-NEXT: result    i32{{$}}
    215 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    216 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    217 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    218 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    219 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    220 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
    221 ; CHECK-NEXT: return    $pop5{{$}}
    222 define i32 @load_test13(i32* %p, i32 %n) {
    223   %add = add nsw i32 10, %n
    224   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
    225   %t = load i32, i32* %arrayidx, align 4
    226   ret i32 %t
    227 }
    228 
    229 ; CHECK-LABEL: load_test14:
    230 ; CHECK-NEXT: param     i32, i32{{$}}
    231 ; CHECK-NEXT: result    i32{{$}}
    232 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    233 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    234 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    235 ; CHECK-NEXT: i32.load  $push3=, 40($pop2){{$}}
    236 ; CHECK-NEXT: return    $pop3{{$}}
    237 define i32 @load_test14(i32* %p, i32 %n) {
    238   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
    239   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
    240   %t = load i32, i32* %add.ptr1, align 4
    241   ret i32 %t
    242 }
    243 
    244 ; CHECK-LABEL: load_test15:
    245 ; CHECK-NEXT: param     i32, i32{{$}}
    246 ; CHECK-NEXT: result    i32{{$}}
    247 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    248 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    249 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    250 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    251 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    252 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
    253 ; CHECK-NEXT: return    $pop5{{$}}
    254 define i32 @load_test15(i32* %p, i32 %n) {
    255   %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
    256   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
    257   %t = load i32, i32* %add.ptr1, align 4
    258   ret i32 %t
    259 }
    260 
    261 ; CHECK-LABEL: load_test16:
    262 ; CHECK-NEXT: param     i32, i32{{$}}
    263 ; CHECK-NEXT: result    i32{{$}}
    264 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    265 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    266 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    267 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    268 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    269 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
    270 ; CHECK-NEXT: return    $pop5{{$}}
    271 define i32 @load_test16(i32* %p, i32 %n) {
    272   %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
    273   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
    274   %t = load i32, i32* %add.ptr1, align 4
    275   ret i32 %t
    276 }
    277 
    278 ; CHECK-LABEL: load_test17:
    279 ; CHECK-NEXT: param     i32, i32{{$}}
    280 ; CHECK-NEXT: result    i32{{$}}
    281 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    282 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    283 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    284 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    285 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    286 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
    287 ; CHECK-NEXT: return    $pop5{{$}}
    288 define i32 @load_test17(i32* %p, i32 %n) {
    289   %add = add nsw i32 %n, 10
    290   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
    291   %t = load i32, i32* %add.ptr, align 4
    292   ret i32 %t
    293 }
    294 
    295 ; CHECK-LABEL: load_test18:
    296 ; CHECK-NEXT: param     i32, i32{{$}}
    297 ; CHECK-NEXT: result    i32{{$}}
    298 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    299 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    300 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    301 ; CHECK-NEXT: i32.load  $push3=, 40($pop2){{$}}
    302 ; CHECK-NEXT: return    $pop3{{$}}
    303 define i32 @load_test18(i32* %p, i32 %n) {
    304   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
    305   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
    306   %t = load i32, i32* %add.ptr1, align 4
    307   ret i32 %t
    308 }
    309 
    310 ; CHECK-LABEL: load_test19:
    311 ; CHECK-NEXT: param     i32, i32{{$}}
    312 ; CHECK-NEXT: result    i32{{$}}
    313 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    314 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    315 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    316 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    317 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    318 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
    319 ; CHECK-NEXT: return    $pop5{{$}}
    320 define i32 @load_test19(i32* %p, i32 %n) {
    321   %add = add nsw i32 10, %n
    322   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
    323   %t = load i32, i32* %add.ptr, align 4
    324   ret i32 %t
    325 }
    326 
    327 ; CHECK-LABEL: load_test20:
    328 ; CHECK-NEXT: param     i32{{$}}
    329 ; CHECK-NEXT: result    i32{{$}}
    330 ; CHECK-NEXT: i32.const $push0=, -40{{$}}
    331 ; CHECK-NEXT: i32.add   $push1=, $0, $pop0{{$}}
    332 ; CHECK-NEXT: i32.load  $push2=, 0($pop1){{$}}
    333 ; CHECK-NEXT: return    $pop2{{$}}
    334 define i32 @load_test20(i32* %p) {
    335   %arrayidx = getelementptr inbounds i32, i32* %p, i32 -10
    336   %t = load i32, i32* %arrayidx, align 4
    337   ret i32 %t
    338 }
    339 
    340 ; CHECK-LABEL: load_test21:
    341 ; CHECK-NEXT: param     i32, i32{{$}}
    342 ; CHECK-NEXT: result    i32{{$}}
    343 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    344 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    345 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    346 ; CHECK-NEXT: i32.const $push3=, -40{{$}}
    347 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    348 ; CHECK-NEXT: i32.load  $push5=, 0($pop4){{$}}
    349 ; CHECK-NEXT: return    $pop5{{$}}
    350 define i32 @load_test21(i32* %p, i32 %n) {
    351   %add = add nsw i32 %n, -10
    352   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
    353   %t = load i32, i32* %arrayidx, align 4
    354   ret i32 %t
    355 }
    356 
    357 ; CHECK-LABEL: store_test0:
    358 ; CHECK-NEXT: param     i32{{$}}
    359 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
    360 ; CHECK-NEXT: i32.store g+40($pop0), $0{{$}}
    361 ; CHECK-NEXT: return{{$}}
    362 define void @store_test0(i32 %i) {
    363   store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
    364   ret void
    365 }
    366 
    367 ; CHECK-LABEL: store_test0_noinbounds:
    368 ; CHECK-NEXT: param     i32{{$}}
    369 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
    370 ; CHECK-NEXT: i32.store g+40($pop0), $0{{$}}
    371 ; CHECK-NEXT: return{{$}}
    372 define void @store_test0_noinbounds(i32 %i) {
    373   store i32 %i, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
    374   ret void
    375 }
    376 
    377 ; CHECK-LABEL: store_test1:
    378 ; CHECK-NEXT: param     i32, i32{{$}}
    379 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    380 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    381 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
    382 ; CHECK-NEX T: return{{$}}
    383 define void @store_test1(i32 %n, i32 %i) {
    384   %add = add nsw i32 %n, 10
    385   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
    386   store i32 %i, i32* %arrayidx, align 4
    387   ret void
    388 }
    389 
    390 ; CHECK-LABEL: store_test2:
    391 ; CHECK-NEXT: param     i32, i32{{$}}
    392 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    393 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    394 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
    395 ; CHECK-NEX T: return{{$}}
    396 define void @store_test2(i32 %n, i32 %i) {
    397   %add = add nsw i32 10, %n
    398   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
    399   store i32 %i, i32* %arrayidx, align 4
    400   ret void
    401 }
    402 
    403 ; CHECK-LABEL: store_test3:
    404 ; CHECK-NEXT: param     i32, i32{{$}}
    405 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    406 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    407 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
    408 ; CHECK-NEX T: return{{$}}
    409 define void @store_test3(i32 %n, i32 %i) {
    410   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
    411   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
    412   store i32 %i, i32* %add.ptr1, align 4
    413   ret void
    414 }
    415 
    416 ; CHECK-LABEL: store_test4:
    417 ; CHECK-NEXT: param     i32, i32{{$}}
    418 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    419 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    420 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
    421 ; CHECK-NEX T: return{{$}}
    422 define void @store_test4(i32 %n, i32 %i) {
    423   %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
    424   store i32 %i, i32* %add.ptr, align 4
    425   ret void
    426 }
    427 
    428 ; CHECK-LABEL: store_test5:
    429 ; CHECK-NEXT: param     i32, i32{{$}}
    430 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    431 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    432 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
    433 ; CHECK-NEX T: return{{$}}
    434 define void @store_test5(i32 %n, i32 %i) {
    435   %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
    436   store i32 %i, i32* %add.ptr, align 4
    437   ret void
    438 }
    439 
    440 ; CHECK-LABEL: store_test6:
    441 ; CHECK-NEXT: param     i32, i32{{$}}
    442 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    443 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    444 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
    445 ; CHECK-NEX T: return{{$}}
    446 define void @store_test6(i32 %n, i32 %i) {
    447   %add = add nsw i32 %n, 10
    448   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
    449   store i32 %i, i32* %add.ptr, align 4
    450   ret void
    451 }
    452 
    453 ; CHECK-LABEL: store_test7:
    454 ; CHECK-NEXT: param     i32, i32{{$}}
    455 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    456 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    457 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
    458 ; CHECK-NEX T: return{{$}}
    459 define void @store_test7(i32 %n, i32 %i) {
    460   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
    461   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
    462   store i32 %i, i32* %add.ptr1, align 4
    463   ret void
    464 }
    465 
    466 ; CHECK-LABEL: store_test8:
    467 ; CHECK-NEXT: param     i32, i32{{$}}
    468 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    469 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    470 ; CHECK-NEX T: i32.store g+40($pop1), $1{{$}}
    471 ; CHECK-NEX T: return{{$}}
    472 define void @store_test8(i32 %n, i32 %i) {
    473   %add = add nsw i32 10, %n
    474   %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
    475   store i32 %i, i32* %add.ptr, align 4
    476   ret void
    477 }
    478 
    479 ; CHECK-LABEL: store_test9:
    480 ; CHECK-NEXT: param     i32{{$}}
    481 ; CHECK-NEXT: i32.const $push0=, 0{{$}}
    482 ; CHECK-NEXT: i32.store g-40($pop0), $0{{$}}
    483 ; CHECK-NEXT: return{{$}}
    484 define void @store_test9(i32 %i) {
    485   store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4
    486   ret void
    487 }
    488 
    489 ; CHECK-LABEL: store_test10:
    490 ; CHECK-NEXT: param     i32, i32{{$}}
    491 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    492 ; CHECK-NEXT: i32.shl   $push1=, $0, $pop0{{$}}
    493 ; CHECK-NEXT: i32.const $push2=, g-40{{$}}
    494 ; CHECK-NEXT: i32.add   $push3=, $pop1, $pop2{{$}}
    495 ; CHECK-NEXT: i32.store 0($pop3), $1{{$}}
    496 ; CHECK-NEXT: return{{$}}
    497 define void @store_test10(i32 %n, i32 %i) {
    498   %add = add nsw i32 %n, -10
    499   %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
    500   store i32 %i, i32* %arrayidx, align 4
    501   ret void
    502 }
    503 
    504 ; CHECK-LABEL: store_test11:
    505 ; CHECK-NEXT: param     i32, i32{{$}}
    506 ; CHECK-NEXT: i32.store 40($0), $1{{$}}
    507 ; CHECK-NEXT: return{{$}}
    508 define void @store_test11(i32* %p, i32 %i) {
    509   %arrayidx = getelementptr inbounds i32, i32* %p, i32 10
    510   store i32 %i, i32* %arrayidx, align 4
    511   ret void
    512 }
    513 
    514 ; CHECK-LABEL: store_test11_noinbounds:
    515 ; CHECK-NEXT: param     i32, i32{{$}}
    516 ; CHECK-NEXT: i32.const $push0=, 40{{$}}
    517 ; CHECK-NEXT: i32.add   $push1=, $0, $pop0{{$}}
    518 ; CHECK-NEXT: i32.store 0($pop1), $1{{$}}
    519 ; CHECK-NEXT: return{{$}}
    520 define void @store_test11_noinbounds(i32* %p, i32 %i) {
    521   %arrayidx = getelementptr i32, i32* %p, i32 10
    522   store i32 %i, i32* %arrayidx, align 4
    523   ret void
    524 }
    525 
    526 ; CHECK-LABEL: store_test12:
    527 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    528 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    529 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    530 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    531 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    532 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    533 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
    534 ; CHECK-NEXT: return{{$}}
    535 define void @store_test12(i32* %p, i32 %n, i32 %i) {
    536   %add = add nsw i32 %n, 10
    537   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
    538   store i32 %i, i32* %arrayidx, align 4
    539   ret void
    540 }
    541 
    542 ; CHECK-LABEL: store_test13:
    543 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    544 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    545 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    546 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    547 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    548 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    549 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
    550 ; CHECK-NEXT: return{{$}}
    551 define void @store_test13(i32* %p, i32 %n, i32 %i) {
    552   %add = add nsw i32 10, %n
    553   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
    554   store i32 %i, i32* %arrayidx, align 4
    555   ret void
    556 }
    557 
    558 ; CHECK-LABEL: store_test14:
    559 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    560 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    561 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    562 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    563 ; CHECK-NEXT: i32.store 40($pop2), $2{{$}}
    564 ; CHECK-NEXT: return{{$}}
    565 define void @store_test14(i32* %p, i32 %n, i32 %i) {
    566   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
    567   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
    568   store i32 %i, i32* %add.ptr1, align 4
    569   ret void
    570 }
    571 
    572 ; CHECK-LABEL: store_test15:
    573 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    574 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    575 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    576 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    577 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    578 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    579 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
    580 ; CHECK-NEXT: return{{$}}
    581 define void @store_test15(i32* %p, i32 %n, i32 %i) {
    582   %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
    583   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
    584   store i32 %i, i32* %add.ptr1, align 4
    585   ret void
    586 }
    587 
    588 ; CHECK-LABEL: store_test16:
    589 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    590 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    591 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    592 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    593 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    594 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    595 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
    596 ; CHECK-NEXT: return{{$}}
    597 define void @store_test16(i32* %p, i32 %n, i32 %i) {
    598   %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
    599   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
    600   store i32 %i, i32* %add.ptr1, align 4
    601   ret void
    602 }
    603 
    604 ; CHECK-LABEL: store_test17:
    605 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    606 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    607 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    608 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    609 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    610 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    611 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
    612 ; CHECK-NEXT: return{{$}}
    613 define void @store_test17(i32* %p, i32 %n, i32 %i) {
    614   %add = add nsw i32 %n, 10
    615   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
    616   store i32 %i, i32* %add.ptr, align 4
    617   ret void
    618 }
    619 
    620 ; CHECK-LABEL: store_test18:
    621 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    622 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    623 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    624 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    625 ; CHECK-NEXT: i32.store 40($pop2), $2{{$}}
    626 ; CHECK-NEXT: return{{$}}
    627 define void @store_test18(i32* %p, i32 %n, i32 %i) {
    628   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
    629   %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
    630   store i32 %i, i32* %add.ptr1, align 4
    631   ret void
    632 }
    633 
    634 ; CHECK-LABEL: store_test19:
    635 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    636 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    637 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    638 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    639 ; CHECK-NEXT: i32.const $push3=, 40{{$}}
    640 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    641 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
    642 ; CHECK-NEXT: return{{$}}
    643 define void @store_test19(i32* %p, i32 %n, i32 %i) {
    644   %add = add nsw i32 10, %n
    645   %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
    646   store i32 %i, i32* %add.ptr, align 4
    647   ret void
    648 }
    649 
    650 ; CHECK-LABEL: store_test20:
    651 ; CHECK-NEXT: param     i32, i32{{$}}
    652 ; CHECK-NEXT: i32.const $push0=, -40{{$}}
    653 ; CHECK-NEXT: i32.add   $push1=, $0, $pop0{{$}}
    654 ; CHECK-NEXT: i32.store 0($pop1), $1{{$}}
    655 ; CHECK-NEXT: return{{$}}
    656 define void @store_test20(i32* %p, i32 %i) {
    657   %arrayidx = getelementptr inbounds i32, i32* %p, i32 -10
    658   store i32 %i, i32* %arrayidx, align 4
    659   ret void
    660 }
    661 
    662 ; CHECK-LABEL: store_test21:
    663 ; CHECK-NEXT: param     i32, i32, i32{{$}}
    664 ; CHECK-NEXT: i32.const $push0=, 2{{$}}
    665 ; CHECK-NEXT: i32.shl   $push1=, $1, $pop0{{$}}
    666 ; CHECK-NEXT: i32.add   $push2=, $0, $pop1{{$}}
    667 ; CHECK-NEXT: i32.const $push3=, -40{{$}}
    668 ; CHECK-NEXT: i32.add   $push4=, $pop2, $pop3{{$}}
    669 ; CHECK-NEXT: i32.store 0($pop4), $2{{$}}
    670 ; CHECK-NEXT: return{{$}}
    671 define void @store_test21(i32* %p, i32 %n, i32 %i) {
    672   %add = add nsw i32 %n, -10
    673   %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
    674   store i32 %i, i32* %arrayidx, align 4
    675   ret void
    676 }
    677