1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -asm-verbose=false | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker 3*9880d681SAndroid Build Coastguard Worker; Test constant load and store address offsets. 4*9880d681SAndroid Build Coastguard Worker 5*9880d681SAndroid Build Coastguard Workertarget datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128" 6*9880d681SAndroid Build Coastguard Workertarget triple = "wasm32-unknown-unknown" 7*9880d681SAndroid Build Coastguard Worker 8*9880d681SAndroid Build Coastguard Worker; With an nuw add, we can fold an offset. 9*9880d681SAndroid Build Coastguard Worker 10*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i32_with_folded_offset: 11*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $push0=, 24($0){{$}} 12*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i32_with_folded_offset(i32* %p) { 13*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i32* %p to i32 14*9880d681SAndroid Build Coastguard Worker %r = add nuw i32 %q, 24 15*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i32* 16*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* %s 17*9880d681SAndroid Build Coastguard Worker ret i32 %t 18*9880d681SAndroid Build Coastguard Worker} 19*9880d681SAndroid Build Coastguard Worker 20*9880d681SAndroid Build Coastguard Worker; With an inbounds gep, we can fold an offset. 21*9880d681SAndroid Build Coastguard Worker 22*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i32_with_folded_gep_offset: 23*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $push0=, 24($0){{$}} 24*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i32_with_folded_gep_offset(i32* %p) { 25*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i32, i32* %p, i32 6 26*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* %s 27*9880d681SAndroid Build Coastguard Worker ret i32 %t 28*9880d681SAndroid Build Coastguard Worker} 29*9880d681SAndroid Build Coastguard Worker 30*9880d681SAndroid Build Coastguard Worker; We can't fold a negative offset though, even with an inbounds gep. 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i32_with_unfolded_gep_negative_offset: 33*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, -24{{$}} 34*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 35*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $push2=, 0($pop1){{$}} 36*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i32_with_unfolded_gep_negative_offset(i32* %p) { 37*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i32, i32* %p, i32 -6 38*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* %s 39*9880d681SAndroid Build Coastguard Worker ret i32 %t 40*9880d681SAndroid Build Coastguard Worker} 41*9880d681SAndroid Build Coastguard Worker 42*9880d681SAndroid Build Coastguard Worker; Without nuw, and even with nsw, we can't fold an offset. 43*9880d681SAndroid Build Coastguard Worker 44*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i32_with_unfolded_offset: 45*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 24{{$}} 46*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 47*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $push2=, 0($pop1){{$}} 48*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i32_with_unfolded_offset(i32* %p) { 49*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i32* %p to i32 50*9880d681SAndroid Build Coastguard Worker %r = add nsw i32 %q, 24 51*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i32* 52*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* %s 53*9880d681SAndroid Build Coastguard Worker ret i32 %t 54*9880d681SAndroid Build Coastguard Worker} 55*9880d681SAndroid Build Coastguard Worker 56*9880d681SAndroid Build Coastguard Worker; Without inbounds, we can't fold a gep offset. 57*9880d681SAndroid Build Coastguard Worker 58*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i32_with_unfolded_gep_offset: 59*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 24{{$}} 60*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 61*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $push2=, 0($pop1){{$}} 62*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i32_with_unfolded_gep_offset(i32* %p) { 63*9880d681SAndroid Build Coastguard Worker %s = getelementptr i32, i32* %p, i32 6 64*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* %s 65*9880d681SAndroid Build Coastguard Worker ret i32 %t 66*9880d681SAndroid Build Coastguard Worker} 67*9880d681SAndroid Build Coastguard Worker 68*9880d681SAndroid Build Coastguard Worker; Same as above but with i64. 69*9880d681SAndroid Build Coastguard Worker 70*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i64_with_folded_offset: 71*9880d681SAndroid Build Coastguard Worker; CHECK: i64.load $push0=, 24($0){{$}} 72*9880d681SAndroid Build Coastguard Workerdefine i64 @load_i64_with_folded_offset(i64* %p) { 73*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i64* %p to i32 74*9880d681SAndroid Build Coastguard Worker %r = add nuw i32 %q, 24 75*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i64* 76*9880d681SAndroid Build Coastguard Worker %t = load i64, i64* %s 77*9880d681SAndroid Build Coastguard Worker ret i64 %t 78*9880d681SAndroid Build Coastguard Worker} 79*9880d681SAndroid Build Coastguard Worker 80*9880d681SAndroid Build Coastguard Worker; Same as above but with i64. 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i64_with_folded_gep_offset: 83*9880d681SAndroid Build Coastguard Worker; CHECK: i64.load $push0=, 24($0){{$}} 84*9880d681SAndroid Build Coastguard Workerdefine i64 @load_i64_with_folded_gep_offset(i64* %p) { 85*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i64, i64* %p, i32 3 86*9880d681SAndroid Build Coastguard Worker %t = load i64, i64* %s 87*9880d681SAndroid Build Coastguard Worker ret i64 %t 88*9880d681SAndroid Build Coastguard Worker} 89*9880d681SAndroid Build Coastguard Worker 90*9880d681SAndroid Build Coastguard Worker; Same as above but with i64. 91*9880d681SAndroid Build Coastguard Worker 92*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i64_with_unfolded_gep_negative_offset: 93*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, -24{{$}} 94*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 95*9880d681SAndroid Build Coastguard Worker; CHECK: i64.load $push2=, 0($pop1){{$}} 96*9880d681SAndroid Build Coastguard Workerdefine i64 @load_i64_with_unfolded_gep_negative_offset(i64* %p) { 97*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i64, i64* %p, i32 -3 98*9880d681SAndroid Build Coastguard Worker %t = load i64, i64* %s 99*9880d681SAndroid Build Coastguard Worker ret i64 %t 100*9880d681SAndroid Build Coastguard Worker} 101*9880d681SAndroid Build Coastguard Worker 102*9880d681SAndroid Build Coastguard Worker; Same as above but with i64. 103*9880d681SAndroid Build Coastguard Worker 104*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i64_with_unfolded_offset: 105*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 24{{$}} 106*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 107*9880d681SAndroid Build Coastguard Worker; CHECK: i64.load $push2=, 0($pop1){{$}} 108*9880d681SAndroid Build Coastguard Workerdefine i64 @load_i64_with_unfolded_offset(i64* %p) { 109*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i64* %p to i32 110*9880d681SAndroid Build Coastguard Worker %r = add nsw i32 %q, 24 111*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i64* 112*9880d681SAndroid Build Coastguard Worker %t = load i64, i64* %s 113*9880d681SAndroid Build Coastguard Worker ret i64 %t 114*9880d681SAndroid Build Coastguard Worker} 115*9880d681SAndroid Build Coastguard Worker 116*9880d681SAndroid Build Coastguard Worker; Same as above but with i64. 117*9880d681SAndroid Build Coastguard Worker 118*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i64_with_unfolded_gep_offset: 119*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 24{{$}} 120*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 121*9880d681SAndroid Build Coastguard Worker; CHECK: i64.load $push2=, 0($pop1){{$}} 122*9880d681SAndroid Build Coastguard Workerdefine i64 @load_i64_with_unfolded_gep_offset(i64* %p) { 123*9880d681SAndroid Build Coastguard Worker %s = getelementptr i64, i64* %p, i32 3 124*9880d681SAndroid Build Coastguard Worker %t = load i64, i64* %s 125*9880d681SAndroid Build Coastguard Worker ret i64 %t 126*9880d681SAndroid Build Coastguard Worker} 127*9880d681SAndroid Build Coastguard Worker 128*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i32_with_folded_or_offset: 129*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load8_s $push{{[0-9]+}}=, 2($pop{{[0-9]+}}){{$}} 130*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i32_with_folded_or_offset(i32 %x) { 131*9880d681SAndroid Build Coastguard Worker %and = and i32 %x, -4 132*9880d681SAndroid Build Coastguard Worker %t0 = inttoptr i32 %and to i8* 133*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i8, i8* %t0, i32 2 134*9880d681SAndroid Build Coastguard Worker %t1 = load i8, i8* %arrayidx, align 1 135*9880d681SAndroid Build Coastguard Worker %conv = sext i8 %t1 to i32 136*9880d681SAndroid Build Coastguard Worker ret i32 %conv 137*9880d681SAndroid Build Coastguard Worker} 138*9880d681SAndroid Build Coastguard Worker 139*9880d681SAndroid Build Coastguard Worker; Same as above but with store. 140*9880d681SAndroid Build Coastguard Worker 141*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i32_with_folded_offset: 142*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 24($0), $pop0{{$}} 143*9880d681SAndroid Build Coastguard Workerdefine void @store_i32_with_folded_offset(i32* %p) { 144*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i32* %p to i32 145*9880d681SAndroid Build Coastguard Worker %r = add nuw i32 %q, 24 146*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i32* 147*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %s 148*9880d681SAndroid Build Coastguard Worker ret void 149*9880d681SAndroid Build Coastguard Worker} 150*9880d681SAndroid Build Coastguard Worker 151*9880d681SAndroid Build Coastguard Worker; Same as above but with store. 152*9880d681SAndroid Build Coastguard Worker 153*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i32_with_folded_gep_offset: 154*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 24($0), $pop0{{$}} 155*9880d681SAndroid Build Coastguard Workerdefine void @store_i32_with_folded_gep_offset(i32* %p) { 156*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i32, i32* %p, i32 6 157*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %s 158*9880d681SAndroid Build Coastguard Worker ret void 159*9880d681SAndroid Build Coastguard Worker} 160*9880d681SAndroid Build Coastguard Worker 161*9880d681SAndroid Build Coastguard Worker; Same as above but with store. 162*9880d681SAndroid Build Coastguard Worker 163*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i32_with_unfolded_gep_negative_offset: 164*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, -24{{$}} 165*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 166*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 0($pop1), $pop2{{$}} 167*9880d681SAndroid Build Coastguard Workerdefine void @store_i32_with_unfolded_gep_negative_offset(i32* %p) { 168*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i32, i32* %p, i32 -6 169*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %s 170*9880d681SAndroid Build Coastguard Worker ret void 171*9880d681SAndroid Build Coastguard Worker} 172*9880d681SAndroid Build Coastguard Worker 173*9880d681SAndroid Build Coastguard Worker; Same as above but with store. 174*9880d681SAndroid Build Coastguard Worker 175*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i32_with_unfolded_offset: 176*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 24{{$}} 177*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 178*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 0($pop1), $pop2{{$}} 179*9880d681SAndroid Build Coastguard Workerdefine void @store_i32_with_unfolded_offset(i32* %p) { 180*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i32* %p to i32 181*9880d681SAndroid Build Coastguard Worker %r = add nsw i32 %q, 24 182*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i32* 183*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %s 184*9880d681SAndroid Build Coastguard Worker ret void 185*9880d681SAndroid Build Coastguard Worker} 186*9880d681SAndroid Build Coastguard Worker 187*9880d681SAndroid Build Coastguard Worker; Same as above but with store. 188*9880d681SAndroid Build Coastguard Worker 189*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i32_with_unfolded_gep_offset: 190*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 24{{$}} 191*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 192*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 0($pop1), $pop2{{$}} 193*9880d681SAndroid Build Coastguard Workerdefine void @store_i32_with_unfolded_gep_offset(i32* %p) { 194*9880d681SAndroid Build Coastguard Worker %s = getelementptr i32, i32* %p, i32 6 195*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %s 196*9880d681SAndroid Build Coastguard Worker ret void 197*9880d681SAndroid Build Coastguard Worker} 198*9880d681SAndroid Build Coastguard Worker 199*9880d681SAndroid Build Coastguard Worker; Same as above but with store with i64. 200*9880d681SAndroid Build Coastguard Worker 201*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i64_with_folded_offset: 202*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store $drop=, 24($0), $pop0{{$}} 203*9880d681SAndroid Build Coastguard Workerdefine void @store_i64_with_folded_offset(i64* %p) { 204*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i64* %p to i32 205*9880d681SAndroid Build Coastguard Worker %r = add nuw i32 %q, 24 206*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i64* 207*9880d681SAndroid Build Coastguard Worker store i64 0, i64* %s 208*9880d681SAndroid Build Coastguard Worker ret void 209*9880d681SAndroid Build Coastguard Worker} 210*9880d681SAndroid Build Coastguard Worker 211*9880d681SAndroid Build Coastguard Worker; Same as above but with store with i64. 212*9880d681SAndroid Build Coastguard Worker 213*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i64_with_folded_gep_offset: 214*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store $drop=, 24($0), $pop0{{$}} 215*9880d681SAndroid Build Coastguard Workerdefine void @store_i64_with_folded_gep_offset(i64* %p) { 216*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i64, i64* %p, i32 3 217*9880d681SAndroid Build Coastguard Worker store i64 0, i64* %s 218*9880d681SAndroid Build Coastguard Worker ret void 219*9880d681SAndroid Build Coastguard Worker} 220*9880d681SAndroid Build Coastguard Worker 221*9880d681SAndroid Build Coastguard Worker; Same as above but with store with i64. 222*9880d681SAndroid Build Coastguard Worker 223*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i64_with_unfolded_gep_negative_offset: 224*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, -24{{$}} 225*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 226*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store $drop=, 0($pop1), $pop2{{$}} 227*9880d681SAndroid Build Coastguard Workerdefine void @store_i64_with_unfolded_gep_negative_offset(i64* %p) { 228*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i64, i64* %p, i32 -3 229*9880d681SAndroid Build Coastguard Worker store i64 0, i64* %s 230*9880d681SAndroid Build Coastguard Worker ret void 231*9880d681SAndroid Build Coastguard Worker} 232*9880d681SAndroid Build Coastguard Worker 233*9880d681SAndroid Build Coastguard Worker; Same as above but with store with i64. 234*9880d681SAndroid Build Coastguard Worker 235*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i64_with_unfolded_offset: 236*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 24{{$}} 237*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 238*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store $drop=, 0($pop1), $pop2{{$}} 239*9880d681SAndroid Build Coastguard Workerdefine void @store_i64_with_unfolded_offset(i64* %p) { 240*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i64* %p to i32 241*9880d681SAndroid Build Coastguard Worker %r = add nsw i32 %q, 24 242*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i64* 243*9880d681SAndroid Build Coastguard Worker store i64 0, i64* %s 244*9880d681SAndroid Build Coastguard Worker ret void 245*9880d681SAndroid Build Coastguard Worker} 246*9880d681SAndroid Build Coastguard Worker 247*9880d681SAndroid Build Coastguard Worker; Same as above but with store with i64. 248*9880d681SAndroid Build Coastguard Worker 249*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i64_with_unfolded_gep_offset: 250*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 24{{$}} 251*9880d681SAndroid Build Coastguard Worker; CHECK: i32.add $push1=, $0, $pop0{{$}} 252*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store $drop=, 0($pop1), $pop2{{$}} 253*9880d681SAndroid Build Coastguard Workerdefine void @store_i64_with_unfolded_gep_offset(i64* %p) { 254*9880d681SAndroid Build Coastguard Worker %s = getelementptr i64, i64* %p, i32 3 255*9880d681SAndroid Build Coastguard Worker store i64 0, i64* %s 256*9880d681SAndroid Build Coastguard Worker ret void 257*9880d681SAndroid Build Coastguard Worker} 258*9880d681SAndroid Build Coastguard Worker 259*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i32_with_folded_or_offset: 260*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store8 $drop=, 2($pop{{[0-9]+}}), $pop{{[0-9]+}}{{$}} 261*9880d681SAndroid Build Coastguard Workerdefine void @store_i32_with_folded_or_offset(i32 %x) { 262*9880d681SAndroid Build Coastguard Worker %and = and i32 %x, -4 263*9880d681SAndroid Build Coastguard Worker %t0 = inttoptr i32 %and to i8* 264*9880d681SAndroid Build Coastguard Worker %arrayidx = getelementptr inbounds i8, i8* %t0, i32 2 265*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %arrayidx, align 1 266*9880d681SAndroid Build Coastguard Worker ret void 267*9880d681SAndroid Build Coastguard Worker} 268*9880d681SAndroid Build Coastguard Worker 269*9880d681SAndroid Build Coastguard Worker; When loading from a fixed address, materialize a zero. 270*9880d681SAndroid Build Coastguard Worker 271*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i32_from_numeric_address 272*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 0{{$}} 273*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $push1=, 42($pop0){{$}} 274*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i32_from_numeric_address() { 275*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 42 to i32* 276*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* %s 277*9880d681SAndroid Build Coastguard Worker ret i32 %t 278*9880d681SAndroid Build Coastguard Worker} 279*9880d681SAndroid Build Coastguard Worker 280*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i32_from_global_address 281*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 0{{$}} 282*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $push1=, gv($pop0){{$}} 283*9880d681SAndroid Build Coastguard Worker@gv = global i32 0 284*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i32_from_global_address() { 285*9880d681SAndroid Build Coastguard Worker %t = load i32, i32* @gv 286*9880d681SAndroid Build Coastguard Worker ret i32 %t 287*9880d681SAndroid Build Coastguard Worker} 288*9880d681SAndroid Build Coastguard Worker 289*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i32_to_numeric_address: 290*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.const $push0=, 0{{$}} 291*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.const $push1=, 0{{$}} 292*9880d681SAndroid Build Coastguard Worker; CHECK-NEXT: i32.store $drop=, 42($pop0), $pop1{{$}} 293*9880d681SAndroid Build Coastguard Workerdefine void @store_i32_to_numeric_address() { 294*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 42 to i32* 295*9880d681SAndroid Build Coastguard Worker store i32 0, i32* %s 296*9880d681SAndroid Build Coastguard Worker ret void 297*9880d681SAndroid Build Coastguard Worker} 298*9880d681SAndroid Build Coastguard Worker 299*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i32_to_global_address: 300*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push0=, 0{{$}} 301*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push1=, 0{{$}} 302*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, gv($pop0), $pop1{{$}} 303*9880d681SAndroid Build Coastguard Workerdefine void @store_i32_to_global_address() { 304*9880d681SAndroid Build Coastguard Worker store i32 0, i32* @gv 305*9880d681SAndroid Build Coastguard Worker ret void 306*9880d681SAndroid Build Coastguard Worker} 307*9880d681SAndroid Build Coastguard Worker 308*9880d681SAndroid Build Coastguard Worker; Fold an offset into a sign-extending load. 309*9880d681SAndroid Build Coastguard Worker 310*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i8_s_with_folded_offset: 311*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load8_s $push0=, 24($0){{$}} 312*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i8_s_with_folded_offset(i8* %p) { 313*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i8* %p to i32 314*9880d681SAndroid Build Coastguard Worker %r = add nuw i32 %q, 24 315*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i8* 316*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %s 317*9880d681SAndroid Build Coastguard Worker %u = sext i8 %t to i32 318*9880d681SAndroid Build Coastguard Worker ret i32 %u 319*9880d681SAndroid Build Coastguard Worker} 320*9880d681SAndroid Build Coastguard Worker 321*9880d681SAndroid Build Coastguard Worker; Fold a gep offset into a sign-extending load. 322*9880d681SAndroid Build Coastguard Worker 323*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i8_s_with_folded_gep_offset: 324*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load8_s $push0=, 24($0){{$}} 325*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i8_s_with_folded_gep_offset(i8* %p) { 326*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i8, i8* %p, i32 24 327*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %s 328*9880d681SAndroid Build Coastguard Worker %u = sext i8 %t to i32 329*9880d681SAndroid Build Coastguard Worker ret i32 %u 330*9880d681SAndroid Build Coastguard Worker} 331*9880d681SAndroid Build Coastguard Worker 332*9880d681SAndroid Build Coastguard Worker; Fold an offset into a zero-extending load. 333*9880d681SAndroid Build Coastguard Worker 334*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i8_u_with_folded_offset: 335*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load8_u $push0=, 24($0){{$}} 336*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i8_u_with_folded_offset(i8* %p) { 337*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i8* %p to i32 338*9880d681SAndroid Build Coastguard Worker %r = add nuw i32 %q, 24 339*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i8* 340*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %s 341*9880d681SAndroid Build Coastguard Worker %u = zext i8 %t to i32 342*9880d681SAndroid Build Coastguard Worker ret i32 %u 343*9880d681SAndroid Build Coastguard Worker} 344*9880d681SAndroid Build Coastguard Worker 345*9880d681SAndroid Build Coastguard Worker; Fold a gep offset into a zero-extending load. 346*9880d681SAndroid Build Coastguard Worker 347*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: load_i8_u_with_folded_gep_offset: 348*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load8_u $push0=, 24($0){{$}} 349*9880d681SAndroid Build Coastguard Workerdefine i32 @load_i8_u_with_folded_gep_offset(i8* %p) { 350*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i8, i8* %p, i32 24 351*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %s 352*9880d681SAndroid Build Coastguard Worker %u = zext i8 %t to i32 353*9880d681SAndroid Build Coastguard Worker ret i32 %u 354*9880d681SAndroid Build Coastguard Worker} 355*9880d681SAndroid Build Coastguard Worker 356*9880d681SAndroid Build Coastguard Worker; Fold an offset into a truncating store. 357*9880d681SAndroid Build Coastguard Worker 358*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i8_with_folded_offset: 359*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store8 $drop=, 24($0), $pop0{{$}} 360*9880d681SAndroid Build Coastguard Workerdefine void @store_i8_with_folded_offset(i8* %p) { 361*9880d681SAndroid Build Coastguard Worker %q = ptrtoint i8* %p to i32 362*9880d681SAndroid Build Coastguard Worker %r = add nuw i32 %q, 24 363*9880d681SAndroid Build Coastguard Worker %s = inttoptr i32 %r to i8* 364*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %s 365*9880d681SAndroid Build Coastguard Worker ret void 366*9880d681SAndroid Build Coastguard Worker} 367*9880d681SAndroid Build Coastguard Worker 368*9880d681SAndroid Build Coastguard Worker; Fold a gep offset into a truncating store. 369*9880d681SAndroid Build Coastguard Worker 370*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: store_i8_with_folded_gep_offset: 371*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store8 $drop=, 24($0), $pop0{{$}} 372*9880d681SAndroid Build Coastguard Workerdefine void @store_i8_with_folded_gep_offset(i8* %p) { 373*9880d681SAndroid Build Coastguard Worker %s = getelementptr inbounds i8, i8* %p, i32 24 374*9880d681SAndroid Build Coastguard Worker store i8 0, i8* %s 375*9880d681SAndroid Build Coastguard Worker ret void 376*9880d681SAndroid Build Coastguard Worker} 377*9880d681SAndroid Build Coastguard Worker 378*9880d681SAndroid Build Coastguard Worker; Fold the offsets when lowering aggregate loads and stores. 379*9880d681SAndroid Build Coastguard Worker 380*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: aggregate_load_store: 381*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $2=, 0($0){{$}} 382*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $3=, 4($0){{$}} 383*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $4=, 8($0){{$}} 384*9880d681SAndroid Build Coastguard Worker; CHECK: i32.load $push0=, 12($0){{$}} 385*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 12($1), $pop0{{$}} 386*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 8($1), $4{{$}} 387*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 4($1), $3{{$}} 388*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 0($1), $2{{$}} 389*9880d681SAndroid Build Coastguard Workerdefine void @aggregate_load_store({i32,i32,i32,i32}* %p, {i32,i32,i32,i32}* %q) { 390*9880d681SAndroid Build Coastguard Worker ; volatile so that things stay in order for the tests above 391*9880d681SAndroid Build Coastguard Worker %t = load volatile {i32,i32,i32,i32}, {i32, i32,i32,i32}* %p 392*9880d681SAndroid Build Coastguard Worker store volatile {i32,i32,i32,i32} %t, {i32, i32,i32,i32}* %q 393*9880d681SAndroid Build Coastguard Worker ret void 394*9880d681SAndroid Build Coastguard Worker} 395*9880d681SAndroid Build Coastguard Worker 396*9880d681SAndroid Build Coastguard Worker; Fold the offsets when lowering aggregate return values. The stores get 397*9880d681SAndroid Build Coastguard Worker; merged into i64 stores. 398*9880d681SAndroid Build Coastguard Worker 399*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: aggregate_return: 400*9880d681SAndroid Build Coastguard Worker; CHECK: i64.const $push[[L0:[0-9]+]]=, 0{{$}} 401*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store $push[[L1:[0-9]+]]=, 8($0):p2align=2, $pop[[L0]]{{$}} 402*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store $drop=, 0($0):p2align=2, $pop[[L1]]{{$}} 403*9880d681SAndroid Build Coastguard Workerdefine {i32,i32,i32,i32} @aggregate_return() { 404*9880d681SAndroid Build Coastguard Worker ret {i32,i32,i32,i32} zeroinitializer 405*9880d681SAndroid Build Coastguard Worker} 406*9880d681SAndroid Build Coastguard Worker 407*9880d681SAndroid Build Coastguard Worker; Fold the offsets when lowering aggregate return values. The stores are not 408*9880d681SAndroid Build Coastguard Worker; merged. 409*9880d681SAndroid Build Coastguard Worker 410*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: aggregate_return_without_merge: 411*9880d681SAndroid Build Coastguard Worker; CHECK: i32.const $push[[L0:[0-9]+]]=, 0{{$}} 412*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store8 $push[[L1:[0-9]+]]=, 14($0), $pop[[L0]]{{$}} 413*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store16 $push[[L2:[0-9]+]]=, 12($0), $pop[[L1]]{{$}} 414*9880d681SAndroid Build Coastguard Worker; CHECK: i32.store $drop=, 8($0), $pop[[L2]]{{$}} 415*9880d681SAndroid Build Coastguard Worker; CHECK: i64.const $push[[L3:[0-9]+]]=, 0{{$}} 416*9880d681SAndroid Build Coastguard Worker; CHECK: i64.store $drop=, 0($0), $pop[[L3]]{{$}} 417*9880d681SAndroid Build Coastguard Workerdefine {i64,i32,i16,i8} @aggregate_return_without_merge() { 418*9880d681SAndroid Build Coastguard Worker ret {i64,i32,i16,i8} zeroinitializer 419*9880d681SAndroid Build Coastguard Worker} 420