diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-02-11 13:25:24 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-02-11 13:25:24 +0000 |
| commit | 3897d3b845ab73af1f4abd7fd8cc6e43925af1b4 (patch) | |
| tree | e11f1177f7adb0f4c18009faf801850cfcd667cb /test/CodeGen | |
| parent | 963c784e8cd41cd556d0f19e090268b2e574e9f0 (diff) | |
Notes
Diffstat (limited to 'test/CodeGen')
| -rw-r--r-- | test/CodeGen/AArch64/ldst-zero.ll | 74 | ||||
| -rw-r--r-- | test/CodeGen/AArch64/misched-stp.ll | 57 | ||||
| -rw-r--r-- | test/CodeGen/AArch64/regcoal-physreg.mir | 95 | ||||
| -rw-r--r-- | test/CodeGen/ARM/machine-copyprop.mir | 22 | ||||
| -rw-r--r-- | test/CodeGen/X86/conditional-tailcall.ll | 53 | ||||
| -rw-r--r-- | test/CodeGen/X86/shrink-compare.ll | 6 | ||||
| -rw-r--r-- | test/CodeGen/X86/tail-call-conditional.mir | 85 |
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 - -... |
