Nikita Popov 78f88082de [ConstantFold] Fix incorrect inbounds inference for [0 x T] GEPs
Previously all indices into [0 x T] arrays were considered in
range, which resulted in us incorrectly inferring inbounds for
all GEPs of that form. We should not consider them in range here,
and instead bail out of the rewriting logic (which would divide
by zero).

Do continue to consider 0 always in range, to avoid changing
behavior for zero-index GEPs.
2023-02-01 15:14:11 +01:00

772 lines
26 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -disable-wasm-fallthrough-return-opt -wasm-disable-explicit-locals -wasm-keep-registers -relocation-model=pic | FileCheck %s
; Test folding constant offsets and symbols into load and store addresses under
; a variety of circumstances.
target triple = "wasm32-unknown-emscripten"
@g = external global [0 x i32], align 4
define i32 @load_test0() {
; CHECK-LABEL: load_test0:
; CHECK: .functype load_test0 () -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push0=, g@GOT
; CHECK-NEXT: i32.load $push1=, 40($pop0)
; CHECK-NEXT: return $pop1
%t = load i32, ptr getelementptr inbounds ([0 x i32], ptr @g, i32 0, i32 10), align 4
ret i32 %t
}
define i32 @load_test0_noinbounds() {
; CHECK-LABEL: load_test0_noinbounds:
; CHECK: .functype load_test0_noinbounds () -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push1=, g@GOT
; CHECK-NEXT: i32.const $push0=, 40
; CHECK-NEXT: i32.add $push2=, $pop1, $pop0
; CHECK-NEXT: i32.load $push3=, 0($pop2)
; CHECK-NEXT: return $pop3
%t = load i32, ptr getelementptr ([0 x i32], ptr @g, i32 0, i32 10), align 4
ret i32 %t
}
; TODO: load_test1 - load_test8 are disabled because folding GA+reg is disabled
; (there are cases where the value in the reg can be negative).
; Likewise for stores.
define i32 @load_test1(i32 %n) {
; CHECK-LABEL: load_test1:
; CHECK: .functype load_test1 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.load $push6=, 0($pop5)
; CHECK-NEXT: return $pop6
%add = add nsw i32 %n, 10
%arrayidx = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define i32 @load_test2(i32 %n) {
; CHECK-LABEL: load_test2:
; CHECK: .functype load_test2 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.load $push6=, 0($pop5)
; CHECK-NEXT: return $pop6
%add = add nsw i32 10, %n
%arrayidx = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define i32 @load_test3(i32 %n) {
; CHECK-LABEL: load_test3:
; CHECK: .functype load_test3 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: i32.add $push3=, $pop2, $pop1
; CHECK-NEXT: i32.load $push4=, 40($pop3)
; CHECK-NEXT: return $pop4
%add.ptr = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %n
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 10
%t = load i32, ptr %add.ptr1, align 4
ret i32 %t
}
define i32 @load_test4(i32 %n) {
; CHECK-LABEL: load_test4:
; CHECK: .functype load_test4 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: i32.add $push3=, $pop2, $pop1
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.load $push6=, 0($pop5)
; CHECK-NEXT: return $pop6
%add.ptr = getelementptr inbounds i32, ptr getelementptr inbounds ([0 x i32], ptr @g, i32 0, i32 10), i32 %n
%t = load i32, ptr %add.ptr, align 4
ret i32 %t
}
define i32 @load_test5(i32 %n) {
; CHECK-LABEL: load_test5:
; CHECK: .functype load_test5 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: i32.add $push3=, $pop2, $pop1
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.load $push6=, 0($pop5)
; CHECK-NEXT: return $pop6
%add.ptr = getelementptr inbounds i32, ptr getelementptr inbounds ([0 x i32], ptr @g, i32 0, i32 10), i32 %n
%t = load i32, ptr %add.ptr, align 4
ret i32 %t
}
define i32 @load_test6(i32 %n) {
; CHECK-LABEL: load_test6:
; CHECK: .functype load_test6 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.load $push6=, 0($pop5)
; CHECK-NEXT: return $pop6
%add = add nsw i32 %n, 10
%add.ptr = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
%t = load i32, ptr %add.ptr, align 4
ret i32 %t
}
define i32 @load_test7(i32 %n) {
; CHECK-LABEL: load_test7:
; CHECK: .functype load_test7 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: i32.add $push3=, $pop2, $pop1
; CHECK-NEXT: i32.load $push4=, 40($pop3)
; CHECK-NEXT: return $pop4
%add.ptr = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %n
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 10
%t = load i32, ptr %add.ptr1, align 4
ret i32 %t
}
define i32 @load_test8(i32 %n) {
; CHECK-LABEL: load_test8:
; CHECK: .functype load_test8 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.load $push6=, 0($pop5)
; CHECK-NEXT: return $pop6
%add = add nsw i32 10, %n
%add.ptr = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
%t = load i32, ptr %add.ptr, align 4
ret i32 %t
}
define i32 @load_test9() {
; CHECK-LABEL: load_test9:
; CHECK: .functype load_test9 () -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push1=, g@GOT
; CHECK-NEXT: i32.const $push0=, -40
; CHECK-NEXT: i32.add $push2=, $pop1, $pop0
; CHECK-NEXT: i32.load $push3=, 0($pop2)
; CHECK-NEXT: return $pop3
%t = load i32, ptr getelementptr inbounds ([0 x i32], ptr @g, i32 0, i32 1073741814), align 4
ret i32 %t
}
define i32 @load_test10(i32 %n) {
; CHECK-LABEL: load_test10:
; CHECK: .functype load_test10 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, -40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.load $push6=, 0($pop5)
; CHECK-NEXT: return $pop6
%add = add nsw i32 %n, -10
%arrayidx = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define i32 @load_test11(ptr %p) {
; CHECK-LABEL: load_test11:
; CHECK: .functype load_test11 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.load $push0=, 40($0)
; CHECK-NEXT: return $pop0
%arrayidx = getelementptr inbounds i32, ptr %p, i32 10
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define i32 @load_test11_noinbounds(ptr %p) {
; CHECK-LABEL: load_test11_noinbounds:
; CHECK: .functype load_test11_noinbounds (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 40
; CHECK-NEXT: i32.add $push1=, $0, $pop0
; CHECK-NEXT: i32.load $push2=, 0($pop1)
; CHECK-NEXT: return $pop2
%arrayidx = getelementptr i32, ptr %p, i32 10
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define i32 @load_test12(ptr %p, i32 %n) {
; CHECK-LABEL: load_test12:
; CHECK: .functype load_test12 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.load $push5=, 0($pop4)
; CHECK-NEXT: return $pop5
%add = add nsw i32 %n, 10
%arrayidx = getelementptr inbounds i32, ptr %p, i32 %add
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define i32 @load_test13(ptr %p, i32 %n) {
; CHECK-LABEL: load_test13:
; CHECK: .functype load_test13 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.load $push5=, 0($pop4)
; CHECK-NEXT: return $pop5
%add = add nsw i32 10, %n
%arrayidx = getelementptr inbounds i32, ptr %p, i32 %add
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define i32 @load_test14(ptr %p, i32 %n) {
; CHECK-LABEL: load_test14:
; CHECK: .functype load_test14 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $0, $pop1
; CHECK-NEXT: i32.load $push3=, 40($pop2)
; CHECK-NEXT: return $pop3
%add.ptr = getelementptr inbounds i32, ptr %p, i32 %n
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 10
%t = load i32, ptr %add.ptr1, align 4
ret i32 %t
}
define i32 @load_test15(ptr %p, i32 %n) {
; CHECK-LABEL: load_test15:
; CHECK: .functype load_test15 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $0, $pop1
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.load $push5=, 0($pop4)
; CHECK-NEXT: return $pop5
%add.ptr = getelementptr inbounds i32, ptr %p, i32 10
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 %n
%t = load i32, ptr %add.ptr1, align 4
ret i32 %t
}
define i32 @load_test16(ptr %p, i32 %n) {
; CHECK-LABEL: load_test16:
; CHECK: .functype load_test16 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $0, $pop1
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.load $push5=, 0($pop4)
; CHECK-NEXT: return $pop5
%add.ptr = getelementptr inbounds i32, ptr %p, i32 10
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 %n
%t = load i32, ptr %add.ptr1, align 4
ret i32 %t
}
define i32 @load_test17(ptr %p, i32 %n) {
; CHECK-LABEL: load_test17:
; CHECK: .functype load_test17 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.load $push5=, 0($pop4)
; CHECK-NEXT: return $pop5
%add = add nsw i32 %n, 10
%add.ptr = getelementptr inbounds i32, ptr %p, i32 %add
%t = load i32, ptr %add.ptr, align 4
ret i32 %t
}
define i32 @load_test18(ptr %p, i32 %n) {
; CHECK-LABEL: load_test18:
; CHECK: .functype load_test18 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $0, $pop1
; CHECK-NEXT: i32.load $push3=, 40($pop2)
; CHECK-NEXT: return $pop3
%add.ptr = getelementptr inbounds i32, ptr %p, i32 %n
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 10
%t = load i32, ptr %add.ptr1, align 4
ret i32 %t
}
define i32 @load_test19(ptr %p, i32 %n) {
; CHECK-LABEL: load_test19:
; CHECK: .functype load_test19 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.load $push5=, 0($pop4)
; CHECK-NEXT: return $pop5
%add = add nsw i32 10, %n
%add.ptr = getelementptr inbounds i32, ptr %p, i32 %add
%t = load i32, ptr %add.ptr, align 4
ret i32 %t
}
define i32 @load_test20(ptr %p) {
; CHECK-LABEL: load_test20:
; CHECK: .functype load_test20 (i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, -40
; CHECK-NEXT: i32.add $push1=, $0, $pop0
; CHECK-NEXT: i32.load $push2=, 0($pop1)
; CHECK-NEXT: return $pop2
%arrayidx = getelementptr inbounds i32, ptr %p, i32 -10
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define i32 @load_test21(ptr %p, i32 %n) {
; CHECK-LABEL: load_test21:
; CHECK: .functype load_test21 (i32, i32) -> (i32)
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, -40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.load $push5=, 0($pop4)
; CHECK-NEXT: return $pop5
%add = add nsw i32 %n, -10
%arrayidx = getelementptr inbounds i32, ptr %p, i32 %add
%t = load i32, ptr %arrayidx, align 4
ret i32 %t
}
define void @store_test0(i32 %i) {
; CHECK-LABEL: store_test0:
; CHECK: .functype store_test0 (i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push0=, g@GOT
; CHECK-NEXT: i32.store 40($pop0), $0
; CHECK-NEXT: return
store i32 %i, ptr getelementptr inbounds ([0 x i32], ptr @g, i32 0, i32 10), align 4
ret void
}
define void @store_test0_noinbounds(i32 %i) {
; CHECK-LABEL: store_test0_noinbounds:
; CHECK: .functype store_test0_noinbounds (i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push1=, g@GOT
; CHECK-NEXT: i32.const $push0=, 40
; CHECK-NEXT: i32.add $push2=, $pop1, $pop0
; CHECK-NEXT: i32.store 0($pop2), $0
; CHECK-NEXT: return
store i32 %i, ptr getelementptr ([0 x i32], ptr @g, i32 0, i32 10), align 4
ret void
}
define void @store_test1(i32 %n, i32 %i) {
; CHECK-LABEL: store_test1:
; CHECK: .functype store_test1 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.store 0($pop5), $1
; CHECK-NEXT: return
%add = add nsw i32 %n, 10
%arrayidx = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
store i32 %i, ptr %arrayidx, align 4
ret void
}
define void @store_test2(i32 %n, i32 %i) {
; CHECK-LABEL: store_test2:
; CHECK: .functype store_test2 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.store 0($pop5), $1
; CHECK-NEXT: return
%add = add nsw i32 10, %n
%arrayidx = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
store i32 %i, ptr %arrayidx, align 4
ret void
}
define void @store_test3(i32 %n, i32 %i) {
; CHECK-LABEL: store_test3:
; CHECK: .functype store_test3 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: i32.add $push3=, $pop2, $pop1
; CHECK-NEXT: i32.store 40($pop3), $1
; CHECK-NEXT: return
%add.ptr = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %n
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 10
store i32 %i, ptr %add.ptr1, align 4
ret void
}
define void @store_test4(i32 %n, i32 %i) {
; CHECK-LABEL: store_test4:
; CHECK: .functype store_test4 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: i32.add $push3=, $pop2, $pop1
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.store 0($pop5), $1
; CHECK-NEXT: return
%add.ptr = getelementptr inbounds i32, ptr getelementptr inbounds ([0 x i32], ptr @g, i32 0, i32 10), i32 %n
store i32 %i, ptr %add.ptr, align 4
ret void
}
define void @store_test5(i32 %n, i32 %i) {
; CHECK-LABEL: store_test5:
; CHECK: .functype store_test5 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: i32.add $push3=, $pop2, $pop1
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.store 0($pop5), $1
; CHECK-NEXT: return
%add.ptr = getelementptr inbounds i32, ptr getelementptr inbounds ([0 x i32], ptr @g, i32 0, i32 10), i32 %n
store i32 %i, ptr %add.ptr, align 4
ret void
}
define void @store_test6(i32 %n, i32 %i) {
; CHECK-LABEL: store_test6:
; CHECK: .functype store_test6 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.store 0($pop5), $1
; CHECK-NEXT: return
%add = add nsw i32 %n, 10
%add.ptr = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
store i32 %i, ptr %add.ptr, align 4
ret void
}
define void @store_test7(i32 %n, i32 %i) {
; CHECK-LABEL: store_test7:
; CHECK: .functype store_test7 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: i32.add $push3=, $pop2, $pop1
; CHECK-NEXT: i32.store 40($pop3), $1
; CHECK-NEXT: return
%add.ptr = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %n
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 10
store i32 %i, ptr %add.ptr1, align 4
ret void
}
define void @store_test8(i32 %n, i32 %i) {
; CHECK-LABEL: store_test8:
; CHECK: .functype store_test8 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, 40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.store 0($pop5), $1
; CHECK-NEXT: return
%add = add nsw i32 10, %n
%add.ptr = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
store i32 %i, ptr %add.ptr, align 4
ret void
}
define void @store_test9(i32 %i) {
; CHECK-LABEL: store_test9:
; CHECK: .functype store_test9 (i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: global.get $push1=, g@GOT
; CHECK-NEXT: i32.const $push0=, -40
; CHECK-NEXT: i32.add $push2=, $pop1, $pop0
; CHECK-NEXT: i32.store 0($pop2), $0
; CHECK-NEXT: return
store i32 %i, ptr getelementptr inbounds ([0 x i32], ptr @g, i32 0, i32 1073741814), align 4
ret void
}
define void @store_test10(i32 %n, i32 %i) {
; CHECK-LABEL: store_test10:
; CHECK: .functype store_test10 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $0, $pop0
; CHECK-NEXT: global.get $push2=, g@GOT
; CHECK-NEXT: i32.add $push3=, $pop1, $pop2
; CHECK-NEXT: i32.const $push4=, -40
; CHECK-NEXT: i32.add $push5=, $pop3, $pop4
; CHECK-NEXT: i32.store 0($pop5), $1
; CHECK-NEXT: return
%add = add nsw i32 %n, -10
%arrayidx = getelementptr inbounds [0 x i32], ptr @g, i32 0, i32 %add
store i32 %i, ptr %arrayidx, align 4
ret void
}
define void @store_test11(ptr %p, i32 %i) {
; CHECK-LABEL: store_test11:
; CHECK: .functype store_test11 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.store 40($0), $1
; CHECK-NEXT: return
%arrayidx = getelementptr inbounds i32, ptr %p, i32 10
store i32 %i, ptr %arrayidx, align 4
ret void
}
define void @store_test11_noinbounds(ptr %p, i32 %i) {
; CHECK-LABEL: store_test11_noinbounds:
; CHECK: .functype store_test11_noinbounds (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 40
; CHECK-NEXT: i32.add $push1=, $0, $pop0
; CHECK-NEXT: i32.store 0($pop1), $1
; CHECK-NEXT: return
%arrayidx = getelementptr i32, ptr %p, i32 10
store i32 %i, ptr %arrayidx, align 4
ret void
}
define void @store_test12(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test12:
; CHECK: .functype store_test12 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.store 0($pop4), $2
; CHECK-NEXT: return
%add = add nsw i32 %n, 10
%arrayidx = getelementptr inbounds i32, ptr %p, i32 %add
store i32 %i, ptr %arrayidx, align 4
ret void
}
define void @store_test13(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test13:
; CHECK: .functype store_test13 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.store 0($pop4), $2
; CHECK-NEXT: return
%add = add nsw i32 10, %n
%arrayidx = getelementptr inbounds i32, ptr %p, i32 %add
store i32 %i, ptr %arrayidx, align 4
ret void
}
define void @store_test14(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test14:
; CHECK: .functype store_test14 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $0, $pop1
; CHECK-NEXT: i32.store 40($pop2), $2
; CHECK-NEXT: return
%add.ptr = getelementptr inbounds i32, ptr %p, i32 %n
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 10
store i32 %i, ptr %add.ptr1, align 4
ret void
}
define void @store_test15(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test15:
; CHECK: .functype store_test15 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $0, $pop1
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.store 0($pop4), $2
; CHECK-NEXT: return
%add.ptr = getelementptr inbounds i32, ptr %p, i32 10
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 %n
store i32 %i, ptr %add.ptr1, align 4
ret void
}
define void @store_test16(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test16:
; CHECK: .functype store_test16 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $0, $pop1
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.store 0($pop4), $2
; CHECK-NEXT: return
%add.ptr = getelementptr inbounds i32, ptr %p, i32 10
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 %n
store i32 %i, ptr %add.ptr1, align 4
ret void
}
define void @store_test17(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test17:
; CHECK: .functype store_test17 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.store 0($pop4), $2
; CHECK-NEXT: return
%add = add nsw i32 %n, 10
%add.ptr = getelementptr inbounds i32, ptr %p, i32 %add
store i32 %i, ptr %add.ptr, align 4
ret void
}
define void @store_test18(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test18:
; CHECK: .functype store_test18 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $0, $pop1
; CHECK-NEXT: i32.store 40($pop2), $2
; CHECK-NEXT: return
%add.ptr = getelementptr inbounds i32, ptr %p, i32 %n
%add.ptr1 = getelementptr inbounds i32, ptr %add.ptr, i32 10
store i32 %i, ptr %add.ptr1, align 4
ret void
}
define void @store_test19(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test19:
; CHECK: .functype store_test19 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, 40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.store 0($pop4), $2
; CHECK-NEXT: return
%add = add nsw i32 10, %n
%add.ptr = getelementptr inbounds i32, ptr %p, i32 %add
store i32 %i, ptr %add.ptr, align 4
ret void
}
define void @store_test20(ptr %p, i32 %i) {
; CHECK-LABEL: store_test20:
; CHECK: .functype store_test20 (i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, -40
; CHECK-NEXT: i32.add $push1=, $0, $pop0
; CHECK-NEXT: i32.store 0($pop1), $1
; CHECK-NEXT: return
%arrayidx = getelementptr inbounds i32, ptr %p, i32 -10
store i32 %i, ptr %arrayidx, align 4
ret void
}
define void @store_test21(ptr %p, i32 %n, i32 %i) {
; CHECK-LABEL: store_test21:
; CHECK: .functype store_test21 (i32, i32, i32) -> ()
; CHECK-NEXT: # %bb.0:
; CHECK-NEXT: i32.const $push0=, 2
; CHECK-NEXT: i32.shl $push1=, $1, $pop0
; CHECK-NEXT: i32.add $push2=, $pop1, $0
; CHECK-NEXT: i32.const $push3=, -40
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3
; CHECK-NEXT: i32.store 0($pop4), $2
; CHECK-NEXT: return
%add = add nsw i32 %n, -10
%arrayidx = getelementptr inbounds i32, ptr %p, i32 %add
store i32 %i, ptr %arrayidx, align 4
ret void
}