summaryrefslogtreecommitdiff
path: root/test/CodeGen
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-02-11 13:25:24 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-02-11 13:25:24 +0000
commit3897d3b845ab73af1f4abd7fd8cc6e43925af1b4 (patch)
treee11f1177f7adb0f4c18009faf801850cfcd667cb /test/CodeGen
parent963c784e8cd41cd556d0f19e090268b2e574e9f0 (diff)
Notes
Diffstat (limited to 'test/CodeGen')
-rw-r--r--test/CodeGen/AArch64/ldst-zero.ll74
-rw-r--r--test/CodeGen/AArch64/misched-stp.ll57
-rw-r--r--test/CodeGen/AArch64/regcoal-physreg.mir95
-rw-r--r--test/CodeGen/ARM/machine-copyprop.mir22
-rw-r--r--test/CodeGen/X86/conditional-tailcall.ll53
-rw-r--r--test/CodeGen/X86/shrink-compare.ll6
-rw-r--r--test/CodeGen/X86/tail-call-conditional.mir85
7 files changed, 240 insertions, 152 deletions
diff --git a/test/CodeGen/AArch64/ldst-zero.ll b/test/CodeGen/AArch64/ldst-zero.ll
new file mode 100644
index 000000000000..95b92ac70879
--- /dev/null
+++ b/test/CodeGen/AArch64/ldst-zero.ll
@@ -0,0 +1,74 @@
+; RUN: llc -mtriple=aarch64 -mcpu=cortex-a53 < %s | FileCheck %s
+
+; Tests to check that zero stores which are generated as STP xzr, xzr aren't
+; scheduled incorrectly due to incorrect alias information
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
+%struct.tree_common = type { i8*, i8*, i32 }
+
+; Original test case which exhibited the bug
+define void @test1(%struct.tree_common* %t, i32 %code, i8* %type) {
+; CHECK-LABEL: test1:
+; CHECK: stp xzr, xzr, [x0, #8]
+; CHECK: stp xzr, x2, [x0]
+; CHECK: str w1, [x0, #16]
+entry:
+ %0 = bitcast %struct.tree_common* %t to i8*
+ tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 24, i32 8, i1 false)
+ %code1 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 2
+ store i32 %code, i32* %code1, align 8
+ %type2 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 1
+ store i8* %type, i8** %type2, align 8
+ ret void
+}
+
+; Store to each struct element instead of using memset
+define void @test2(%struct.tree_common* %t, i32 %code, i8* %type) {
+; CHECK-LABEL: test2:
+; CHECK: stp xzr, xzr, [x0]
+; CHECK: str wzr, [x0, #16]
+; CHECK: str w1, [x0, #16]
+; CHECK: str x2, [x0, #8]
+entry:
+ %0 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 0
+ %1 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 1
+ %2 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 2
+ store i8* zeroinitializer, i8** %0, align 8
+ store i8* zeroinitializer, i8** %1, align 8
+ store i32 zeroinitializer, i32* %2, align 8
+ store i32 %code, i32* %2, align 8
+ store i8* %type, i8** %1, align 8
+ ret void
+}
+
+; Vector store instead of memset
+define void @test3(%struct.tree_common* %t, i32 %code, i8* %type) {
+; CHECK-LABEL: test3:
+; CHECK: stp xzr, xzr, [x0, #8]
+; CHECK: stp xzr, x2, [x0]
+; CHECK: str w1, [x0, #16]
+entry:
+ %0 = bitcast %struct.tree_common* %t to <3 x i64>*
+ store <3 x i64> zeroinitializer, <3 x i64>* %0, align 8
+ %code1 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 2
+ store i32 %code, i32* %code1, align 8
+ %type2 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 1
+ store i8* %type, i8** %type2, align 8
+ ret void
+}
+
+; Vector store, then store to vector elements
+define void @test4(<3 x i64>* %p, i64 %x, i64 %y) {
+; CHECK-LABEL: test4:
+; CHECK: stp xzr, xzr, [x0, #8]
+; CHECK: stp xzr, x2, [x0]
+; CHECK: str x1, [x0, #16]
+entry:
+ store <3 x i64> zeroinitializer, <3 x i64>* %p, align 8
+ %0 = bitcast <3 x i64>* %p to i64*
+ %1 = getelementptr inbounds i64, i64* %0, i64 2
+ store i64 %x, i64* %1, align 8
+ %2 = getelementptr inbounds i64, i64* %0, i64 1
+ store i64 %y, i64* %2, align 8
+ ret void
+}
diff --git a/test/CodeGen/AArch64/misched-stp.ll b/test/CodeGen/AArch64/misched-stp.ll
new file mode 100644
index 000000000000..4ea481cae68e
--- /dev/null
+++ b/test/CodeGen/AArch64/misched-stp.ll
@@ -0,0 +1,57 @@
+; REQUIRES: asserts
+; RUN: llc < %s -mtriple=aarch64 -mcpu=cyclone -mattr=+use-aa -enable-misched -verify-misched -debug-only=misched -o - 2>&1 > /dev/null | FileCheck %s
+
+; Tests to check that the scheduler dependencies derived from alias analysis are
+; correct when we have loads that have been split up so that they can later be
+; merged into STP.
+
+; CHECK: ********** MI Scheduling **********
+; CHECK: test_splat:BB#0 entry
+; CHECK: SU({{[0-9]+}}): STRWui %vreg{{[0-9]+}}, %vreg{{[0-9]+}}, 3; mem:ST4[%3+8]
+; CHECK: Successors:
+; CHECK-NEXT: ord [[SU1:SU\([0-9]+\)]]
+; CHECK: SU({{[0-9]+}}): STRWui %vreg{{[0-9]+}}, %vreg{{[0-9]+}}, 2; mem:ST4[%3+4]
+; CHECK: Successors:
+; CHECK-NEXT: ord [[SU2:SU\([0-9]+\)]]
+; CHECK: [[SU1]]: STRWui %vreg{{[0-9]+}}, %vreg{{[0-9]+}}, 3; mem:ST4[%2]
+; CHECK: [[SU2]]: STRWui %vreg{{[0-9]+}}, %vreg{{[0-9]+}}, 2; mem:ST4[%1]
+define void @test_splat(i32 %x, i32 %y, i32* %p) {
+entry:
+ %val = load i32, i32* %p, align 4
+ %0 = getelementptr inbounds i32, i32* %p, i64 1
+ %1 = getelementptr inbounds i32, i32* %p, i64 2
+ %2 = getelementptr inbounds i32, i32* %p, i64 3
+ %vec0 = insertelement <4 x i32> undef, i32 %val, i32 0
+ %vec1 = insertelement <4 x i32> %vec0, i32 %val, i32 1
+ %vec2 = insertelement <4 x i32> %vec1, i32 %val, i32 2
+ %vec3 = insertelement <4 x i32> %vec2, i32 %val, i32 3
+ %3 = bitcast i32* %0 to <4 x i32>*
+ store <4 x i32> %vec3, <4 x i32>* %3, align 4
+ store i32 %x, i32* %2, align 4
+ store i32 %y, i32* %1, align 4
+ ret void
+}
+
+declare void @llvm.memset.p0i8.i64(i8* nocapture, i8, i64, i32, i1)
+%struct.tree_common = type { i8*, i8*, i32 }
+
+; CHECK: ********** MI Scheduling **********
+; CHECK: test_zero:BB#0 entry
+; CHECK: SU({{[0-9]+}}): STRXui %XZR, %vreg{{[0-9]+}}, 2; mem:ST8[%0+16]
+; CHECK: Successors:
+; CHECK-NEXT: ord [[SU3:SU\([0-9]+\)]]
+; CHECK: SU({{[0-9]+}}): STRXui %XZR, %vreg{{[0-9]+}}, 1; mem:ST8[%0+8]
+; CHECK: Successors:
+; CHECK-NEXT: ord [[SU4:SU\([0-9]+\)]]
+; CHECK: [[SU3]]: STRWui %vreg{{[0-9]+}}, %vreg{{[0-9]+}}, 4; mem:ST4[%code1]
+; CHECK: [[SU4]]: STRXui %vreg{{[0-9]+}}, %vreg{{[0-9]+}}, 1; mem:ST8[%type2]
+define void @test_zero(%struct.tree_common* %t, i32 %code, i8* %type) {
+entry:
+ %0 = bitcast %struct.tree_common* %t to i8*
+ tail call void @llvm.memset.p0i8.i64(i8* %0, i8 0, i64 24, i32 8, i1 false)
+ %code1 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 2
+ store i32 %code, i32* %code1, align 8
+ %type2 = getelementptr inbounds %struct.tree_common, %struct.tree_common* %t, i64 0, i32 1
+ store i8* %type, i8** %type2, align 8
+ ret void
+}
diff --git a/test/CodeGen/AArch64/regcoal-physreg.mir b/test/CodeGen/AArch64/regcoal-physreg.mir
index e1c4d703003e..c6133991171b 100644
--- a/test/CodeGen/AArch64/regcoal-physreg.mir
+++ b/test/CodeGen/AArch64/regcoal-physreg.mir
@@ -1,19 +1,24 @@
# RUN: llc -mtriple=aarch64-apple-ios -run-pass=simple-register-coalescing %s -o - | FileCheck %s
--- |
- define void @func() { ret void }
+ define void @func0() { ret void }
+ define void @func1() { ret void }
+ define void @func2() { ret void }
...
---
# Check coalescing of COPYs from reserved physregs.
-# CHECK-LABEL: name: func
-name: func
+# CHECK-LABEL: name: func0
+name: func0
registers:
- - { id: 0, class: gpr32 }
- - { id: 1, class: gpr64 }
- - { id: 2, class: gpr64 }
- - { id: 3, class: gpr32 }
- - { id: 4, class: gpr64 }
- - { id: 5, class: gpr32 }
- - { id: 6, class: xseqpairsclass }
+ - { id: 0, class: gpr32 }
+ - { id: 1, class: gpr64 }
+ - { id: 2, class: gpr64 }
+ - { id: 3, class: gpr32 }
+ - { id: 4, class: gpr64 }
+ - { id: 5, class: gpr32 }
+ - { id: 6, class: xseqpairsclass }
+ - { id: 7, class: gpr64 }
+ - { id: 8, class: gpr64sp }
+ - { id: 9, class: gpr64sp }
body: |
bb.0:
; We usually should not coalesce copies from allocatable physregs.
@@ -60,8 +65,74 @@ body: |
; Only coalesce when the source register is reserved as a whole (this is
; a limitation of the current code which cannot update liveness information
; of the non-reserved part).
- ; CHECK: %6 = COPY %xzr_x0
+ ; CHECK: %6 = COPY %x28_fp
; CHECK: HINT 0, implicit %6
- %6 = COPY %xzr_x0
+ %6 = COPY %x28_fp
HINT 0, implicit %6
+
+ ; This can be coalesced.
+ ; CHECK: %fp = SUBXri %fp, 4, 0
+ %8 = SUBXri %fp, 4, 0
+ %fp = COPY %8
+
+ ; Cannot coalesce when there are reads of the physreg.
+ ; CHECK-NOT: %fp = SUBXri %fp, 8, 0
+ ; CHECK: %9 = SUBXri %fp, 8, 0
+ ; CHECK: STRXui %fp, %fp, 0
+ ; CHECK: %fp = COPY %9
+ %9 = SUBXri %fp, 8, 0
+ STRXui %fp, %fp, 0
+ %fp = COPY %9
+...
+---
+# Check coalescing of COPYs from reserved physregs.
+# CHECK-LABEL: name: func1
+name: func1
+registers:
+ - { id: 0, class: gpr64sp }
+body: |
+ bb.0:
+ successors: %bb.1, %bb.2
+ ; Cannot coalesce physreg because we have reads on other CFG paths (we
+ ; currently abort for any control flow)
+ ; CHECK-NOT: %fp = SUBXri
+ ; CHECK: %0 = SUBXri %fp, 12, 0
+ ; CHECK: CBZX undef %x0, %bb.1
+ ; CHECK: B %bb.2
+ %0 = SUBXri %fp, 12, 0
+ CBZX undef %x0, %bb.1
+ B %bb.2
+
+ bb.1:
+ %fp = COPY %0
+ RET_ReallyLR
+
+ bb.2:
+ STRXui %fp, %fp, 0
+ RET_ReallyLR
+...
+---
+# CHECK-LABEL: name: func2
+name: func2
+registers:
+ - { id: 0, class: gpr64sp }
+body: |
+ bb.0:
+ successors: %bb.1, %bb.2
+ ; We can coalesce copies from physreg to vreg across multiple blocks.
+ ; CHECK-NOT: COPY
+ ; CHECK: CBZX undef %x0, %bb.1
+ ; CHECK-NEXT: B %bb.2
+ %0 = COPY %fp
+ CBZX undef %x0, %bb.1
+ B %bb.2
+
+ bb.1:
+ ; CHECK: STRXui undef %x0, %fp, 0
+ ; CHECK-NEXT: RET_ReallyLR
+ STRXui undef %x0, %0, 0
+ RET_ReallyLR
+
+ bb.2:
+ RET_ReallyLR
...
diff --git a/test/CodeGen/ARM/machine-copyprop.mir b/test/CodeGen/ARM/machine-copyprop.mir
new file mode 100644
index 000000000000..9be595f690db
--- /dev/null
+++ b/test/CodeGen/ARM/machine-copyprop.mir
@@ -0,0 +1,22 @@
+# RUN: llc -o - %s -mtriple=armv7s-- -run-pass=machine-cp | FileCheck %s
+---
+# Test that machine copy prop recognizes the implicit-def operands on a COPY
+# as clobbering the register.
+# CHECK-LABEL: name: func
+# CHECK: %d2 = VMOVv2i32 2, 14, _
+# CHECK: %s5 = COPY %s0, implicit %q1, implicit-def %q1
+# CHECK: VST1q32 %r0, 0, %q1, 14, _
+# The following two COPYs must not be removed
+# CHECK: %s4 = COPY %s20, implicit-def %q1
+# CHECK: %s5 = COPY %s0, implicit killed %d0, implicit %q1, implicit-def %q1
+# CHECK: VST1q32 %r2, 0, %q1, 14, _
+name: func
+body: |
+ bb.0:
+ %d2 = VMOVv2i32 2, 14, _
+ %s5 = COPY %s0, implicit %q1, implicit-def %q1
+ VST1q32 %r0, 0, %q1, 14, _
+ %s4 = COPY %s20, implicit-def %q1
+ %s5 = COPY %s0, implicit killed %d0, implicit %q1, implicit-def %q1
+ VST1q32 %r2, 0, %q1, 14, _
+...
diff --git a/test/CodeGen/X86/conditional-tailcall.ll b/test/CodeGen/X86/conditional-tailcall.ll
deleted file mode 100644
index 502643d9a917..000000000000
--- a/test/CodeGen/X86/conditional-tailcall.ll
+++ /dev/null
@@ -1,53 +0,0 @@
-; RUN: llc < %s -mtriple=i686-linux -show-mc-encoding | FileCheck %s
-; RUN: llc < %s -mtriple=x86_64-linux -show-mc-encoding | FileCheck %s
-
-declare void @foo()
-declare void @bar()
-
-define void @f(i32 %x, i32 %y) optsize {
-entry:
- %p = icmp eq i32 %x, %y
- br i1 %p, label %bb1, label %bb2
-bb1:
- tail call void @foo()
- ret void
-bb2:
- tail call void @bar()
- ret void
-
-; CHECK-LABEL: f:
-; CHECK: cmp
-; CHECK: jne bar
-; Check that the asm doesn't just look good, but uses the correct encoding.
-; CHECK: encoding: [0x75,A]
-; CHECK: jmp foo
-}
-
-
-declare x86_thiscallcc zeroext i1 @baz(i8*, i32)
-define x86_thiscallcc zeroext i1 @BlockPlacementTest(i8* %this, i32 %x) optsize {
-entry:
- %and = and i32 %x, 42
- %tobool = icmp eq i32 %and, 0
- br i1 %tobool, label %land.end, label %land.rhs
-
-land.rhs:
- %and6 = and i32 %x, 44
- %tobool7 = icmp eq i32 %and6, 0
- br i1 %tobool7, label %lor.rhs, label %land.end
-
-lor.rhs:
- %call = tail call x86_thiscallcc zeroext i1 @baz(i8* %this, i32 %x) #2
- br label %land.end
-
-land.end:
- %0 = phi i1 [ false, %entry ], [ true, %land.rhs ], [ %call, %lor.rhs ]
- ret i1 %0
-
-; Make sure machine block placement isn't confused by the conditional tail call,
-; but sees that it can fall through to the next block.
-; CHECK-LABEL: BlockPlacementTest
-; CHECK: je baz
-; CHECK-NOT: xor
-; CHECK: ret
-}
diff --git a/test/CodeGen/X86/shrink-compare.ll b/test/CodeGen/X86/shrink-compare.ll
index 41f5d2d5be23..11facc4f009d 100644
--- a/test/CodeGen/X86/shrink-compare.ll
+++ b/test/CodeGen/X86/shrink-compare.ll
@@ -93,7 +93,8 @@ if.end:
; CHECK-LABEL: test2_1:
; CHECK: movzbl
; CHECK: cmpl $256
-; CHECK: je bar
+; CHECK: jne .LBB
+; CHECK: jmp bar
define void @test2_1(i32 %X) nounwind minsize {
entry:
%and = and i32 %X, 255
@@ -223,7 +224,8 @@ if.end:
; CHECK-LABEL: test_sext_i8_icmp_255:
; CHECK: movb $1,
; CHECK: testb
-; CHECK: je bar
+; CHECK: jne .LBB
+; CHECK: jmp bar
define void @test_sext_i8_icmp_255(i8 %x) nounwind minsize {
entry:
%sext = sext i8 %x to i32
diff --git a/test/CodeGen/X86/tail-call-conditional.mir b/test/CodeGen/X86/tail-call-conditional.mir
deleted file mode 100644
index 75cb1e451d83..000000000000
--- a/test/CodeGen/X86/tail-call-conditional.mir
+++ /dev/null
@@ -1,85 +0,0 @@
-# RUN: llc -mtriple x86_64-- -verify-machineinstrs -run-pass branch-folder -o - %s | FileCheck %s
-
-# Check the TCRETURNdi64cc optimization.
-
---- |
- target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
-
- define i64 @test(i64 %arg, i8* %arg1) optsize {
- %tmp = icmp ult i64 %arg, 100
- br i1 %tmp, label %1, label %4
-
- %tmp3 = icmp ult i64 %arg, 10
- br i1 %tmp3, label %2, label %3
-
- %tmp5 = tail call i64 @f1(i8* %arg1, i64 %arg)
- ret i64 %tmp5
-
- %tmp7 = tail call i64 @f2(i8* %arg1, i64 %arg)
- ret i64 %tmp7
-
- ret i64 123
- }
-
- declare i64 @f1(i8*, i64)
- declare i64 @f2(i8*, i64)
-
-...
----
-name: test
-tracksRegLiveness: true
-liveins:
- - { reg: '%rdi' }
- - { reg: '%rsi' }
-body: |
- bb.0:
- successors: %bb.1, %bb.4
- liveins: %rdi, %rsi
-
- %rax = COPY %rdi
- CMP64ri8 %rax, 99, implicit-def %eflags
- JA_1 %bb.4, implicit %eflags
- JMP_1 %bb.1
-
- ; CHECK: bb.1:
- ; CHECK-NEXT: successors: %bb.2({{[^)]+}}){{$}}
- ; CHECK-NEXT: liveins: %rax, %rsi
- ; CHECK-NEXT: {{^ $}}
- ; CHECK-NEXT: %rdi = COPY %rsi
- ; CHECK-NEXT: %rsi = COPY %rax
- ; CHECK-NEXT: CMP64ri8 %rax, 9, implicit-def %eflags
- ; CHECK-NEXT: TCRETURNdi64cc @f1, 0, 3, csr_64, implicit %rsp, implicit %eflags, implicit %rsp, implicit %rdi, implicit %rsi
-
- bb.1:
- successors: %bb.2, %bb.3
- liveins: %rax, %rsi
-
- CMP64ri8 %rax, 9, implicit-def %eflags
- JA_1 %bb.3, implicit %eflags
- JMP_1 %bb.2
-
- bb.2:
- liveins: %rax, %rsi
-
- %rdi = COPY %rsi
- %rsi = COPY %rax
-
- TCRETURNdi64 @f1, 0, csr_64, implicit %rsp, implicit %rdi, implicit %rsi
-
- ; CHECK: bb.2:
- ; CHECK-NEXT: liveins: %rax, %rdi, %rsi
- ; CHECK-NEXT: {{^ $}}
- ; CHECK-NEXT: TCRETURNdi64 @f2, 0, csr_64, implicit %rsp, implicit %rdi, implicit %rsi
-
- bb.3:
- liveins: %rax, %rsi
-
- %rdi = COPY %rsi
- %rsi = COPY %rax
- TCRETURNdi64 @f2, 0, csr_64, implicit %rsp, implicit %rdi, implicit %rsi
-
- bb.4:
- dead %eax = MOV32ri64 123, implicit-def %rax
- RET 0, %rax
-
-...