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