summaryrefslogtreecommitdiffstats
path: root/llvm/test
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2016-01-22 03:57:34 +0000
committerDan Gohman <dan433584@gmail.com>2016-01-22 03:57:34 +0000
commit0bf3ae84cada4bbc6e21b70952e0bf8b723d8cd4 (patch)
treeaf99a8d9c638cecd47f2ec6301db79eea9b77edf /llvm/test
parentd05b899252b6108ba73bbd88dbd4f51dc09e5119 (diff)
downloadbcm5719-llvm-0bf3ae84cada4bbc6e21b70952e0bf8b723d8cd4.tar.gz
bcm5719-llvm-0bf3ae84cada4bbc6e21b70952e0bf8b723d8cd4.zip
[SelectionDAG] Fold more offsets into GlobalAddresses
This reapplies r258296 and r258366, and also fixes an existing bug in SelectionDAG.cpp's isMemSrcFromString, neglecting to account for the offset in a GlobalAddressSDNode, which is uncovered by those patches. llvm-svn: 258482
Diffstat (limited to 'llvm/test')
-rw-r--r--llvm/test/CodeGen/WebAssembly/address-offsets.ll672
-rw-r--r--llvm/test/CodeGen/X86/lea-opt.ll18
-rw-r--r--llvm/test/CodeGen/X86/memcpy-from-string.ll24
-rw-r--r--llvm/test/CodeGen/X86/negative-offset.ll18
-rw-r--r--llvm/test/CodeGen/XCore/threads.ll4
5 files changed, 725 insertions, 11 deletions
diff --git a/llvm/test/CodeGen/WebAssembly/address-offsets.ll b/llvm/test/CodeGen/WebAssembly/address-offsets.ll
new file mode 100644
index 00000000000..46d16d2b926
--- /dev/null
+++ b/llvm/test/CodeGen/WebAssembly/address-offsets.ll
@@ -0,0 +1,672 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+; Test folding constant offsets and symbols into load and store addresses under
+; a variety of circumstances.
+
+target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
+target triple = "wasm32-unknown-unknown"
+
+@g = external global [0 x i32], align 4
+
+; CHECK-LABEL: load_test0:
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: i32.load $push1=, g+40($pop0){{$}}
+; CHECK-NEXT: return $pop1{{$}}
+define i32 @load_test0() {
+ %t = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test0_noinbounds:
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: i32.load $push1=, g+40($pop0){{$}}
+; CHECK-NEXT: return $pop1{{$}}
+define i32 @load_test0_noinbounds() {
+ %t = load i32, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test1:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test1(i32 %n) {
+ %add = add nsw i32 %n, 10
+ %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test2:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test2(i32 %n) {
+ %add = add nsw i32 10, %n
+ %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test3:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test3(i32 %n) {
+ %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
+ %t = load i32, i32* %add.ptr1, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test4:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test4(i32 %n) {
+ %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
+ %t = load i32, i32* %add.ptr, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test5:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test5(i32 %n) {
+ %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
+ %t = load i32, i32* %add.ptr, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test6:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test6(i32 %n) {
+ %add = add nsw i32 %n, 10
+ %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ %t = load i32, i32* %add.ptr, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test7:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test7(i32 %n) {
+ %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
+ %t = load i32, i32* %add.ptr1, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test8:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, g+40($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test8(i32 %n) {
+ %add = add nsw i32 10, %n
+ %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ %t = load i32, i32* %add.ptr, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test9:
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: i32.load $push1=, g-40($pop0){{$}}
+; CHECK-NEXT: return $pop1{{$}}
+define i32 @load_test9() {
+ %t = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test10:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.const $push2=, g-40{{$}}
+; CHECK-NEXT: i32.add $push3=, $pop1, $pop2{{$}}
+; CHECK-NEXT: i32.load $push4=, 0($pop3){{$}}
+; CHECK-NEXT: return $pop4{{$}}
+define i32 @load_test10(i32 %n) {
+ %add = add nsw i32 %n, -10
+ %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test11:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.load $push0=, 40($0){{$}}
+; CHECK-NEXT: return $pop0{{$}}
+define i32 @load_test11(i32* %p) {
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 10
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test11_noinbounds:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 40{{$}}
+; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, 0($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test11_noinbounds(i32* %p) {
+ %arrayidx = getelementptr i32, i32* %p, i32 10
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test12:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test12(i32* %p, i32 %n) {
+ %add = add nsw i32 %n, 10
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test13:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test13(i32* %p, i32 %n) {
+ %add = add nsw i32 10, %n
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test14:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test14(i32* %p, i32 %n) {
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
+ %t = load i32, i32* %add.ptr1, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test15:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test15(i32* %p, i32 %n) {
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
+ %t = load i32, i32* %add.ptr1, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test16:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test16(i32* %p, i32 %n) {
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
+ %t = load i32, i32* %add.ptr1, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test17:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test17(i32* %p, i32 %n) {
+ %add = add nsw i32 %n, 10
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
+ %t = load i32, i32* %add.ptr, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test18:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test18(i32* %p, i32 %n) {
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
+ %t = load i32, i32* %add.ptr1, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test19:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test19(i32* %p, i32 %n) {
+ %add = add nsw i32 10, %n
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
+ %t = load i32, i32* %add.ptr, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test20:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; CHECK-NEXT: i32.const $push0=, -40{{$}}
+; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.load $push2=, 0($pop1){{$}}
+; CHECK-NEXT: return $pop2{{$}}
+define i32 @load_test20(i32* %p) {
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 -10
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: load_test21:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: result i32{{$}}
+; 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{{$}}
+define i32 @load_test21(i32* %p, i32 %n) {
+ %add = add nsw i32 %n, -10
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
+ %t = load i32, i32* %arrayidx, align 4
+ ret i32 %t
+}
+
+; CHECK-LABEL: store_test0:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop0), $0{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test0(i32 %i) {
+ store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test0_noinbounds:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop0), $0{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test0_noinbounds(i32 %i) {
+ store i32 %i, i32* getelementptr ([0 x i32], [0 x i32]* @g, i32 0, i32 10), align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test1:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test1(i32 %n, i32 %i) {
+ %add = add nsw i32 %n, 10
+ %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test2:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test2(i32 %n, i32 %i) {
+ %add = add nsw i32 10, %n
+ %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test3:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test3(i32 %n, i32 %i) {
+ %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
+ store i32 %i, i32* %add.ptr1, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test4:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test4(i32 %n, i32 %i) {
+ %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
+ store i32 %i, i32* %add.ptr, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test5:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test5(i32 %n, i32 %i) {
+ %add.ptr = getelementptr inbounds i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 10), i32 %n
+ store i32 %i, i32* %add.ptr, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test6:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test6(i32 %n, i32 %i) {
+ %add = add nsw i32 %n, 10
+ %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ store i32 %i, i32* %add.ptr, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test7:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test7(i32 %n, i32 %i) {
+ %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %n
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
+ store i32 %i, i32* %add.ptr1, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test8:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, g+40($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test8(i32 %n, i32 %i) {
+ %add = add nsw i32 10, %n
+ %add.ptr = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ store i32 %i, i32* %add.ptr, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test9:
+; CHECK-NEXT: param i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 0{{$}}
+; CHECK-NEXT: i32.store $discard=, g-40($pop0), $0{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test9(i32 %i) {
+ store i32 %i, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @g, i32 0, i32 1073741814), align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test10:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.const $push2=, g-40{{$}}
+; CHECK-NEXT: i32.add $push3=, $pop1, $pop2{{$}}
+; CHECK-NEXT: i32.store $discard=, 0($pop3), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test10(i32 %n, i32 %i) {
+ %add = add nsw i32 %n, -10
+ %arrayidx = getelementptr inbounds [0 x i32], [0 x i32]* @g, i32 0, i32 %add
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test11:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.store $discard=, 40($0), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test11(i32* %p, i32 %i) {
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 10
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test11_noinbounds:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 40{{$}}
+; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, 0($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test11_noinbounds(i32* %p, i32 %i) {
+ %arrayidx = getelementptr i32, i32* %p, i32 10
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test12:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; 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 $discard=, 0($pop4), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test12(i32* %p, i32 %n, i32 %i) {
+ %add = add nsw i32 %n, 10
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test13:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; 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 $discard=, 0($pop4), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test13(i32* %p, i32 %n, i32 %i) {
+ %add = add nsw i32 10, %n
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test14:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}}
+; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
+; CHECK-NEXT: i32.store $discard=, 40($pop2), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test14(i32* %p, i32 %n, i32 %i) {
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
+ store i32 %i, i32* %add.ptr1, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test15:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; 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 $discard=, 0($pop4), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test15(i32* %p, i32 %n, i32 %i) {
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
+ store i32 %i, i32* %add.ptr1, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test16:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; 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 $discard=, 0($pop4), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test16(i32* %p, i32 %n, i32 %i) {
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 10
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %n
+ store i32 %i, i32* %add.ptr1, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test17:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; 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 $discard=, 0($pop4), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test17(i32* %p, i32 %n, i32 %i) {
+ %add = add nsw i32 %n, 10
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
+ store i32 %i, i32* %add.ptr, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test18:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, 2{{$}}
+; CHECK-NEXT: i32.shl $push1=, $1, $pop0{{$}}
+; CHECK-NEXT: i32.add $push2=, $0, $pop1{{$}}
+; CHECK-NEXT: i32.store $discard=, 40($pop2), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test18(i32* %p, i32 %n, i32 %i) {
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 %n
+ %add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 10
+ store i32 %i, i32* %add.ptr1, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test19:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; 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 $discard=, 0($pop4), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test19(i32* %p, i32 %n, i32 %i) {
+ %add = add nsw i32 10, %n
+ %add.ptr = getelementptr inbounds i32, i32* %p, i32 %add
+ store i32 %i, i32* %add.ptr, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test20:
+; CHECK-NEXT: param i32, i32{{$}}
+; CHECK-NEXT: i32.const $push0=, -40{{$}}
+; CHECK-NEXT: i32.add $push1=, $0, $pop0{{$}}
+; CHECK-NEXT: i32.store $discard=, 0($pop1), $1{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test20(i32* %p, i32 %i) {
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 -10
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
+
+; CHECK-LABEL: store_test21:
+; CHECK-NEXT: param i32, i32, i32{{$}}
+; 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 $discard=, 0($pop4), $2{{$}}
+; CHECK-NEXT: return{{$}}
+define void @store_test21(i32* %p, i32 %n, i32 %i) {
+ %add = add nsw i32 %n, -10
+ %arrayidx = getelementptr inbounds i32, i32* %p, i32 %add
+ store i32 %i, i32* %arrayidx, align 4
+ ret void
+}
diff --git a/llvm/test/CodeGen/X86/lea-opt.ll b/llvm/test/CodeGen/X86/lea-opt.ll
index 8096bfabd6c..20e27773195 100644
--- a/llvm/test/CodeGen/X86/lea-opt.ll
+++ b/llvm/test/CodeGen/X86/lea-opt.ll
@@ -34,12 +34,12 @@ sw.bb.2: ; preds = %entry
sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
ret void
; CHECK-LABEL: test1:
-; CHECK: leaq (%rdi,%rdi,2), [[REG1:%[a-z]+]]
-; CHECK: movl arr1(,[[REG1]],4), {{.*}}
-; CHECK: leaq arr1+4(,[[REG1]],4), [[REG2:%[a-z]+]]
-; CHECK: subl arr1+4(,[[REG1]],4), {{.*}}
-; CHECK: leaq arr1+8(,[[REG1]],4), [[REG3:%[a-z]+]]
-; CHECK: addl arr1+8(,[[REG1]],4), {{.*}}
+; CHECK: shlq $2, [[REG1:%[a-z]+]]
+; CHECK: movl arr1([[REG1]],[[REG1]],2), {{.*}}
+; CHECK: leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]]
+; CHECK: subl arr1+4([[REG1]],[[REG1]],2), {{.*}}
+; CHECK: leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]]
+; CHECK: addl arr1+8([[REG1]],[[REG1]],2), {{.*}}
; CHECK: movl ${{[1-4]+}}, ([[REG2]])
; CHECK: movl ${{[1-4]+}}, ([[REG3]])
; CHECK: movl ${{[1-4]+}}, ([[REG2]])
@@ -74,11 +74,11 @@ sw.bb.2: ; preds = %entry
sw.epilog: ; preds = %sw.bb.2, %sw.bb.1, %entry
ret void
; CHECK-LABEL: test2:
-; CHECK: leaq (%rdi,%rdi,2), [[REG1:%[a-z]+]]
-; CHECK: leaq arr1+4(,[[REG1]],4), [[REG2:%[a-z]+]]
+; CHECK: shlq $2, [[REG1:%[a-z]+]]
+; CHECK: leaq arr1+4([[REG1]],[[REG1]],2), [[REG2:%[a-z]+]]
; CHECK: movl -4([[REG2]]), {{.*}}
; CHECK: subl ([[REG2]]), {{.*}}
-; CHECK: leaq arr1+8(,[[REG1]],4), [[REG3:%[a-z]+]]
+; CHECK: leaq arr1+8([[REG1]],[[REG1]],2), [[REG3:%[a-z]+]]
; CHECK: addl ([[REG3]]), {{.*}}
; CHECK: movl ${{[1-4]+}}, ([[REG2]])
; CHECK: movl ${{[1-4]+}}, ([[REG3]])
diff --git a/llvm/test/CodeGen/X86/memcpy-from-string.ll b/llvm/test/CodeGen/X86/memcpy-from-string.ll
new file mode 100644
index 00000000000..d62d9e20254
--- /dev/null
+++ b/llvm/test/CodeGen/X86/memcpy-from-string.ll
@@ -0,0 +1,24 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+%0 = type { %1, i64, %2 }
+%1 = type { i8* }
+%2 = type { i64, [8 x i8] }
+
+@0 = internal constant [10 x i8] c"asdf jkl;\00", align 1
+
+; Memcpy lowering should emit stores of immediates containing string data from
+; the correct offsets.
+
+; CHECK-LABEL: foo:
+; CHECK: movb $0, 6(%rdi)
+; CHECK: movw $15212, 4(%rdi)
+; CHECK: movl $1802117222, (%rdi)
+define void @foo(i8* %tmp2) {
+ call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* getelementptr inbounds ([10 x i8], [10 x i8]* @0, i64 0, i64 3), i64 7, i32 1, i1 false)
+ ret void
+}
+
+declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
diff --git a/llvm/test/CodeGen/X86/negative-offset.ll b/llvm/test/CodeGen/X86/negative-offset.ll
new file mode 100644
index 00000000000..dc1b255d020
--- /dev/null
+++ b/llvm/test/CodeGen/X86/negative-offset.ll
@@ -0,0 +1,18 @@
+; RUN: llc < %s -asm-verbose=false | FileCheck %s
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Test that a constant consisting of a global symbol with a negative offset
+; is properly folded and isel'd.
+
+; CHECK-LABEL: negative_offset:
+; CHECK: movl $G, %eax
+; CHECK: notq %rax
+; CHECK: addq %rdi, %rax
+; CHECK: retq
+@G = external global [8 x i32]
+define i8* @negative_offset(i8* %a) {
+ %t = getelementptr i8, i8* %a, i64 sub (i64 -1, i64 ptrtoint ([8 x i32]* @G to i64))
+ ret i8* %t
+}
diff --git a/llvm/test/CodeGen/XCore/threads.ll b/llvm/test/CodeGen/XCore/threads.ll
index 0c25314295d..30dda143e08 100644
--- a/llvm/test/CodeGen/XCore/threads.ll
+++ b/llvm/test/CodeGen/XCore/threads.ll
@@ -87,7 +87,7 @@ define i32* @f_tle() {
; CHECK: shl [[R0:r[0-9]]], r11, 3
; CHECK: ldaw [[R1:r[0-9]]], dp[tle]
; r0 = &tl + id*8
-; CHECK: add r0, [[R1]], [[R0]]
+; CHECK: add r0, [[R0]], [[R1]]
ret i32* getelementptr inbounds ([2 x i32], [2 x i32]* @tle, i32 0, i32 0)
}
@@ -96,7 +96,7 @@ define i32 @f_tlExpr () {
; CHECK: get r11, id
; CHECK: shl [[R0:r[0-9]]], r11, 3
; CHECK: ldaw [[R1:r[0-9]]], dp[tle]
-; CHECK: add [[R2:r[0-9]]], [[R1]], [[R0]]
+; CHECK: add [[R2:r[0-9]]], [[R0]], [[R1]]
; CHECK: add r0, [[R2]], [[R2]]
ret i32 add(
i32 ptrtoint( i32* getelementptr inbounds ([2 x i32], [2 x i32]* @tle, i32 0, i32 0) to i32),
OpenPOWER on IntegriCloud