aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGen/AArch64
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-26 19:45:00 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-26 19:45:00 +0000
commit12f3ca4cdb95b193af905a00e722a4dcb40b3de3 (patch)
treeae1a7fcfc24a8d4b23206c57121c3f361d4b7f84 /test/CodeGen/AArch64
parentd99dafe2e4a385dd2a6c76da6d8258deb100657b (diff)
Notes
Diffstat (limited to 'test/CodeGen/AArch64')
-rw-r--r--test/CodeGen/AArch64/GlobalISel/select-pr32733.mir65
-rw-r--r--test/CodeGen/AArch64/arm64-vmul.ll16
-rw-r--r--test/CodeGen/AArch64/fence-singlethread.ll21
-rw-r--r--test/CodeGen/AArch64/optimize-imm.ll64
-rw-r--r--test/CodeGen/AArch64/swiftself-scavenger.ll82
5 files changed, 240 insertions, 8 deletions
diff --git a/test/CodeGen/AArch64/GlobalISel/select-pr32733.mir b/test/CodeGen/AArch64/GlobalISel/select-pr32733.mir
new file mode 100644
index 000000000000..96436209451b
--- /dev/null
+++ b/test/CodeGen/AArch64/GlobalISel/select-pr32733.mir
@@ -0,0 +1,65 @@
+# RUN: llc -mtriple=aarch64-- -run-pass=instruction-select -verify-machineinstrs -global-isel %s -o - | FileCheck %s
+
+--- |
+ define i32 @main() {
+ entry:
+ ret i32 0
+ }
+
+ declare i32 @printf(i8*, ...)
+...
+---
+# CHECK-LABEL: name: main
+name: main
+alignment: 2
+exposesReturnsTwice: false
+noVRegs: false
+legalized: true
+regBankSelected: true
+selected: false
+tracksRegLiveness: true
+registers:
+ - { id: 0, class: gpr }
+ - { id: 1, class: gpr }
+ - { id: 2, class: gpr }
+ - { id: 3, class: gpr }
+ - { id: 4, class: gpr }
+ - { id: 5, class: gpr }
+ - { id: 6, class: gpr }
+ - { id: 7, class: gpr }
+ - { id: 8, class: gpr }
+ - { id: 9, class: gpr }
+ - { id: 10, class: gpr }
+ - { id: 11, class: gpr }
+ - { id: 12, class: gpr }
+ - { id: 13, class: gpr }
+ - { id: 14, class: gpr }
+ - { id: 15, class: gpr }
+frameInfo:
+ isFrameAddressTaken: false
+ isReturnAddressTaken: false
+ hasStackMap: false
+ hasPatchPoint: false
+ stackSize: 0
+ offsetAdjustment: 0
+ maxAlignment: 8
+ adjustsStack: false
+ hasCalls: true
+ maxCallFrameSize: 0
+ hasOpaqueSPAdjustment: false
+ hasVAStart: false
+ hasMustTailInVarArgFunc: false
+# CHECK: body:
+# CHECK: %1 = COPY %w0
+# CHECK-NOT: %2 = ORNWrr %wzr, %1
+# CHECK: %4 = EONWrr %1, %3
+body: |
+ bb.1.entry:
+ liveins: %w0
+ %0(s32) = G_CONSTANT i32 -1
+ %3(s32) = G_CONSTANT i32 1
+ %1(s32) = COPY %w0
+ %2(s32) = G_XOR %1, %0
+ %4(s32) = G_XOR %2, %3
+ %w0 = COPY %4(s32)
+...
diff --git a/test/CodeGen/AArch64/arm64-vmul.ll b/test/CodeGen/AArch64/arm64-vmul.ll
index a5fa78abb92f..a7668ec97979 100644
--- a/test/CodeGen/AArch64/arm64-vmul.ll
+++ b/test/CodeGen/AArch64/arm64-vmul.ll
@@ -1201,35 +1201,35 @@ define <2 x i64> @umlsl_lane_2d(<2 x i32>* %A, <2 x i32>* %B, <2 x i64>* %C) nou
; Scalar FMULX
define float @fmulxs(float %a, float %b) nounwind {
; CHECK-LABEL: fmulxs:
-; CHECKNEXT: fmulx s0, s0, s1
+; CHECK-NEXT: fmulx s0, s0, s1
%fmulx.i = tail call float @llvm.aarch64.neon.fmulx.f32(float %a, float %b) nounwind
-; CHECKNEXT: ret
+; CHECK-NEXT: ret
ret float %fmulx.i
}
define double @fmulxd(double %a, double %b) nounwind {
; CHECK-LABEL: fmulxd:
-; CHECKNEXT: fmulx d0, d0, d1
+; CHECK-NEXT: fmulx d0, d0, d1
%fmulx.i = tail call double @llvm.aarch64.neon.fmulx.f64(double %a, double %b) nounwind
-; CHECKNEXT: ret
+; CHECK-NEXT: ret
ret double %fmulx.i
}
define float @fmulxs_lane(float %a, <4 x float> %vec) nounwind {
; CHECK-LABEL: fmulxs_lane:
-; CHECKNEXT: fmulx.s s0, s0, v1[3]
+; CHECK-NEXT: fmulx.s s0, s0, v1[3]
%b = extractelement <4 x float> %vec, i32 3
%fmulx.i = tail call float @llvm.aarch64.neon.fmulx.f32(float %a, float %b) nounwind
-; CHECKNEXT: ret
+; CHECK-NEXT: ret
ret float %fmulx.i
}
define double @fmulxd_lane(double %a, <2 x double> %vec) nounwind {
; CHECK-LABEL: fmulxd_lane:
-; CHECKNEXT: fmulx d0, d0, v1[1]
+; CHECK-NEXT: fmulx.d d0, d0, v1[1]
%b = extractelement <2 x double> %vec, i32 1
%fmulx.i = tail call double @llvm.aarch64.neon.fmulx.f64(double %a, double %b) nounwind
-; CHECKNEXT: ret
+; CHECK-NEXT: ret
ret double %fmulx.i
}
diff --git a/test/CodeGen/AArch64/fence-singlethread.ll b/test/CodeGen/AArch64/fence-singlethread.ll
new file mode 100644
index 000000000000..2ed744277385
--- /dev/null
+++ b/test/CodeGen/AArch64/fence-singlethread.ll
@@ -0,0 +1,21 @@
+; RUN: llc -mtriple=aarch64-linux-gnu %s -o - | FileCheck %s --check-prefix=LINUX
+; RUN: llc -mtriple=aarch64-apple-ios %s -o - | FileCheck %s --check-prefix=IOS
+; RUN: llc -mtriple=aarch64-linux-gnueabihf %s -filetype=obj -o %t
+; RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=OBJ
+
+; OBJ-NOT: dmb
+
+define void @fence_singlethread() {
+; LINUX-LABEL: fence_singlethread:
+; LINUX-NOT: dmb
+; LINUX: // COMPILER BARRIER
+; LINUX-NOT: dmb
+
+; IOS-LABEL: fence_singlethread:
+; IOS-NOT: dmb
+; IOS: ; COMPILER BARRIER
+; IOS-NOT: dmb
+
+ fence singlethread seq_cst
+ ret void
+}
diff --git a/test/CodeGen/AArch64/optimize-imm.ll b/test/CodeGen/AArch64/optimize-imm.ll
new file mode 100644
index 000000000000..a4725c65aa26
--- /dev/null
+++ b/test/CodeGen/AArch64/optimize-imm.ll
@@ -0,0 +1,64 @@
+; RUN: llc -o - %s -mtriple=aarch64-- | FileCheck %s
+
+; CHECK-LABEL: and1:
+; CHECK: and {{w[0-9]+}}, w0, #0xfffffffd
+
+define void @and1(i32 %a, i8* nocapture %p) {
+entry:
+ %and = and i32 %a, 253
+ %conv = trunc i32 %and to i8
+ store i8 %conv, i8* %p, align 1
+ ret void
+}
+
+; (a & 0x3dfd) | 0xffffc000
+;
+; CHECK-LABEL: and2:
+; CHECK: and {{w[0-9]+}}, w0, #0xfdfdfdfd
+
+define i32 @and2(i32 %a) {
+entry:
+ %and = and i32 %a, 15869
+ %or = or i32 %and, -16384
+ ret i32 %or
+}
+
+; (a & 0x19) | 0xffffffc0
+;
+; CHECK-LABEL: and3:
+; CHECK: and {{w[0-9]+}}, w0, #0x99999999
+
+define i32 @and3(i32 %a) {
+entry:
+ %and = and i32 %a, 25
+ %or = or i32 %and, -64
+ ret i32 %or
+}
+
+; (a & 0xc5600) | 0xfff1f1ff
+;
+; CHECK-LABEL: and4:
+; CHECK: and {{w[0-9]+}}, w0, #0xfffc07ff
+
+define i32 @and4(i32 %a) {
+entry:
+ %and = and i32 %a, 787968
+ %or = or i32 %and, -921089
+ ret i32 %or
+}
+
+; Make sure we don't shrink or optimize an XOR's immediate operand if the
+; immediate is -1. Instruction selection turns (and ((xor $mask, -1), $v0)) into
+; a BIC.
+
+; CHECK-LABEL: xor1:
+; CHECK: orr [[R0:w[0-9]+]], wzr, #0x38
+; CHECK: bic {{w[0-9]+}}, [[R0]], w0, lsl #3
+
+define i32 @xor1(i32 %a) {
+entry:
+ %shl = shl i32 %a, 3
+ %xor = and i32 %shl, 56
+ %and = xor i32 %xor, 56
+ ret i32 %and
+}
diff --git a/test/CodeGen/AArch64/swiftself-scavenger.ll b/test/CodeGen/AArch64/swiftself-scavenger.ll
new file mode 100644
index 000000000000..6d0278440931
--- /dev/null
+++ b/test/CodeGen/AArch64/swiftself-scavenger.ll
@@ -0,0 +1,82 @@
+; RUN: llc -o - %s | FileCheck %s
+; Check that we reserve an emergency spill slot, even if we added an extra
+; CSR spill for the values used by the swiftself parameter.
+; CHECK-LABEL: func:
+; CHECK: str [[REG:x[0-9]+]], [sp, #8]
+; CHECK: add [[REG]], sp, #248
+; CHECK: str xzr, [{{\s*}}[[REG]], #32760]
+; CHECK: ldr x30, [sp, #8]
+target triple = "arm64-apple-ios"
+
+@ptr8 = external global i8*
+@ptr64 = external global i64
+
+define hidden swiftcc void @func(i8* swiftself %arg) #0 {
+bb:
+ %stack0 = alloca i8*, i32 5000, align 8
+ %stack1 = alloca i8*, i32 32, align 8
+
+ %v0 = load volatile i64, i64* @ptr64, align 8
+ %v1 = load volatile i64, i64* @ptr64, align 8
+ %v2 = load volatile i64, i64* @ptr64, align 8
+ %v3 = load volatile i64, i64* @ptr64, align 8
+ %v4 = load volatile i64, i64* @ptr64, align 8
+ %v5 = load volatile i64, i64* @ptr64, align 8
+ %v6 = load volatile i64, i64* @ptr64, align 8
+ %v7 = load volatile i64, i64* @ptr64, align 8
+ %v8 = load volatile i64, i64* @ptr64, align 8
+ %v9 = load volatile i64, i64* @ptr64, align 8
+ %v10 = load volatile i64, i64* @ptr64, align 8
+ %v11 = load volatile i64, i64* @ptr64, align 8
+ %v12 = load volatile i64, i64* @ptr64, align 8
+ %v13 = load volatile i64, i64* @ptr64, align 8
+ %v14 = load volatile i64, i64* @ptr64, align 8
+ %v15 = load volatile i64, i64* @ptr64, align 8
+ %v16 = load volatile i64, i64* @ptr64, align 8
+ %v17 = load volatile i64, i64* @ptr64, align 8
+ %v18 = load volatile i64, i64* @ptr64, align 8
+ %v19 = load volatile i64, i64* @ptr64, align 8
+ %v20 = load volatile i64, i64* @ptr64, align 8
+ %v21 = load volatile i64, i64* @ptr64, align 8
+ %v22 = load volatile i64, i64* @ptr64, align 8
+ %v23 = load volatile i64, i64* @ptr64, align 8
+ %v24 = load volatile i64, i64* @ptr64, align 8
+ %v25 = load volatile i64, i64* @ptr64, align 8
+
+ ; this should exceed stack-relative addressing limits and need an emergency
+ ; spill slot.
+ %s = getelementptr inbounds i8*, i8** %stack0, i64 4092
+ store volatile i8* null, i8** %s
+ store volatile i8* null, i8** %stack1
+
+ store volatile i64 %v0, i64* @ptr64, align 8
+ store volatile i64 %v1, i64* @ptr64, align 8
+ store volatile i64 %v2, i64* @ptr64, align 8
+ store volatile i64 %v3, i64* @ptr64, align 8
+ store volatile i64 %v4, i64* @ptr64, align 8
+ store volatile i64 %v5, i64* @ptr64, align 8
+ store volatile i64 %v6, i64* @ptr64, align 8
+ store volatile i64 %v7, i64* @ptr64, align 8
+ store volatile i64 %v8, i64* @ptr64, align 8
+ store volatile i64 %v9, i64* @ptr64, align 8
+ store volatile i64 %v10, i64* @ptr64, align 8
+ store volatile i64 %v11, i64* @ptr64, align 8
+ store volatile i64 %v12, i64* @ptr64, align 8
+ store volatile i64 %v13, i64* @ptr64, align 8
+ store volatile i64 %v14, i64* @ptr64, align 8
+ store volatile i64 %v15, i64* @ptr64, align 8
+ store volatile i64 %v16, i64* @ptr64, align 8
+ store volatile i64 %v17, i64* @ptr64, align 8
+ store volatile i64 %v18, i64* @ptr64, align 8
+ store volatile i64 %v19, i64* @ptr64, align 8
+ store volatile i64 %v20, i64* @ptr64, align 8
+ store volatile i64 %v21, i64* @ptr64, align 8
+ store volatile i64 %v22, i64* @ptr64, align 8
+ store volatile i64 %v23, i64* @ptr64, align 8
+ store volatile i64 %v24, i64* @ptr64, align 8
+ store volatile i64 %v25, i64* @ptr64, align 8
+
+ ; use swiftself parameter late so it stays alive throughout the function.
+ store volatile i8* %arg, i8** @ptr8
+ ret void
+}