diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2017-05-03 20:26:11 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2017-05-03 20:26:11 +0000 |
| commit | 148779df305667b6942fee7e758fdf81a6498f38 (patch) | |
| tree | 976d85fb9cb4bc8ed54348b045f742be90e10c57 /test/CodeGen | |
| parent | a303c417bbdb53703c2c17398b08486bde78f1f6 (diff) | |
Notes
Diffstat (limited to 'test/CodeGen')
22 files changed, 793 insertions, 187 deletions
diff --git a/test/CodeGen/AMDGPU/promote-alloca-calling-conv.ll b/test/CodeGen/AMDGPU/promote-alloca-calling-conv.ll new file mode 100644 index 0000000000000..a95e9f828b615 --- /dev/null +++ b/test/CodeGen/AMDGPU/promote-alloca-calling-conv.ll @@ -0,0 +1,74 @@ +; RUN: opt -S -mtriple=amdgcn-unknown-unknown -amdgpu-promote-alloca < %s | FileCheck -check-prefix=IR %s +; RUN: llc -march=amdgcn -mcpu=tonga < %s | FileCheck -check-prefix=ASM %s + +; IR-LABEL: define amdgpu_vs void @promote_alloca_shaders(i32 addrspace(1)* inreg %out, i32 addrspace(1)* inreg %in) #0 { +; IR: alloca [5 x i32] +; ASM-LABEL: {{^}}promote_alloca_shaders: +; ASM: ; LDSByteSize: 0 bytes/workgroup (compile time only) + +define amdgpu_vs void @promote_alloca_shaders(i32 addrspace(1)* inreg %out, i32 addrspace(1)* inreg %in) #0 { +entry: + %stack = alloca [5 x i32], align 4 + %tmp0 = load i32, i32 addrspace(1)* %in, align 4 + %arrayidx1 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 %tmp0 + store i32 4, i32* %arrayidx1, align 4 + %arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 1 + %tmp1 = load i32, i32 addrspace(1)* %arrayidx2, align 4 + %arrayidx3 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 %tmp1 + store i32 5, i32* %arrayidx3, align 4 + %arrayidx4 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 0 + %tmp2 = load i32, i32* %arrayidx4, align 4 + store i32 %tmp2, i32 addrspace(1)* %out, align 4 + %arrayidx5 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 1 + %tmp3 = load i32, i32* %arrayidx5 + %arrayidx6 = getelementptr inbounds i32, i32 addrspace(1)* %out, i32 1 + store i32 %tmp3, i32 addrspace(1)* %arrayidx6 + ret void +} + +; OPT-LABEL: @promote_to_vector_call_c( +; OPT-NOT: alloca +; OPT: extractelement <2 x i32> %{{[0-9]+}}, i32 %in +; ASM-NOT: LDSByteSize +define void @promote_to_vector_call_c(i32 addrspace(1)* %out, i32 %in) #0 { +entry: + %tmp = alloca [2 x i32] + %tmp1 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 0 + %tmp2 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 1 + store i32 0, i32* %tmp1 + store i32 1, i32* %tmp2 + %tmp3 = getelementptr [2 x i32], [2 x i32]* %tmp, i32 0, i32 %in + %tmp4 = load i32, i32* %tmp3 + %tmp5 = load volatile i32, i32 addrspace(1)* undef + %tmp6 = add i32 %tmp4, %tmp5 + store i32 %tmp6, i32 addrspace(1)* %out + ret void +} + +; OPT-LABEL: @no_promote_to_lds_c( +; OPT: alloca +; ASM-NOT: LDSByteSize +define void @no_promote_to_lds(i32 addrspace(1)* nocapture %out, i32 addrspace(1)* nocapture %in) #0 { +entry: + %stack = alloca [5 x i32], align 4 + %0 = load i32, i32 addrspace(1)* %in, align 4 + %arrayidx1 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 %0 + store i32 4, i32* %arrayidx1, align 4 + %arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 1 + %1 = load i32, i32 addrspace(1)* %arrayidx2, align 4 + %arrayidx3 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 %1 + store i32 5, i32* %arrayidx3, align 4 + %arrayidx10 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 0 + %2 = load i32, i32* %arrayidx10, align 4 + store i32 %2, i32 addrspace(1)* %out, align 4 + %arrayidx12 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 1 + %3 = load i32, i32* %arrayidx12 + %arrayidx13 = getelementptr inbounds i32, i32 addrspace(1)* %out, i32 1 + store i32 %3, i32 addrspace(1)* %arrayidx13 + ret void +} + +declare i32 @llvm.amdgcn.workitem.id.x() #1 + +attributes #0 = { nounwind "amdgpu-max-work-group-size"="64" } +attributes #1 = { nounwind readnone } diff --git a/test/CodeGen/AMDGPU/promote-alloca-shaders.ll b/test/CodeGen/AMDGPU/promote-alloca-shaders.ll deleted file mode 100644 index d40fca9f4fd5e..0000000000000 --- a/test/CodeGen/AMDGPU/promote-alloca-shaders.ll +++ /dev/null @@ -1,29 +0,0 @@ -; RUN: opt -S -mtriple=amdgcn-unknown-unknown -amdgpu-promote-alloca < %s | FileCheck -check-prefix=IR %s -; RUN: llc -march=amdgcn -mcpu=tonga < %s | FileCheck -check-prefix=ASM %s - -; IR-LABEL: define amdgpu_vs void @promote_alloca_shaders(i32 addrspace(1)* inreg %out, i32 addrspace(1)* inreg %in) #0 { -; IR: alloca [5 x i32] -; ASM-LABEL: {{^}}promote_alloca_shaders: -; ASM: ; LDSByteSize: 0 bytes/workgroup (compile time only) - -define amdgpu_vs void @promote_alloca_shaders(i32 addrspace(1)* inreg %out, i32 addrspace(1)* inreg %in) #0 { -entry: - %stack = alloca [5 x i32], align 4 - %tmp0 = load i32, i32 addrspace(1)* %in, align 4 - %arrayidx1 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 %tmp0 - store i32 4, i32* %arrayidx1, align 4 - %arrayidx2 = getelementptr inbounds i32, i32 addrspace(1)* %in, i32 1 - %tmp1 = load i32, i32 addrspace(1)* %arrayidx2, align 4 - %arrayidx3 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 %tmp1 - store i32 5, i32* %arrayidx3, align 4 - %arrayidx4 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 0 - %tmp2 = load i32, i32* %arrayidx4, align 4 - store i32 %tmp2, i32 addrspace(1)* %out, align 4 - %arrayidx5 = getelementptr inbounds [5 x i32], [5 x i32]* %stack, i32 0, i32 1 - %tmp3 = load i32, i32* %arrayidx5 - %arrayidx6 = getelementptr inbounds i32, i32 addrspace(1)* %out, i32 1 - store i32 %tmp3, i32 addrspace(1)* %arrayidx6 - ret void -} - -attributes #0 = { nounwind "amdgpu-max-work-group-size"="64" } diff --git a/test/CodeGen/ARM/build-attributes.ll b/test/CodeGen/ARM/build-attributes.ll index 699ef6e92a4ff..bef7bbe01bff5 100644 --- a/test/CodeGen/ARM/build-attributes.ll +++ b/test/CodeGen/ARM/build-attributes.ll @@ -199,7 +199,8 @@ ; RUN: llc < %s -mtriple=armv6-none-linux-gnueabi -mcpu=arm1136j-s -mattr=+strict-align | FileCheck %s --check-prefix=STRICT-ALIGN ; RUN: llc < %s -mtriple=armv6-none-linux-gnueabi -mcpu=arm1136j-s | FileCheck %s --check-prefix=NO-STRICT-ALIGN ; ARMv6k -; RUN: llc < %s -mtriple=armv6k-none-netbsd-gnueabi -mcpu=arm1176j-s | FileCheck %s --check-prefix=NO-STRICT-ALIGN +; RUN: llc < %s -mtriple=armv6k-none-netbsd-gnueabi -mcpu=arm1176j-s 2> %t | FileCheck %s --check-prefix=NO-STRICT-ALIGN +; RUN: FileCheck %s < %t --allow-empty --check-prefix=CPU-SUPPORTED ; RUN: llc < %s -mtriple=armv6k-none-linux-gnueabi -mcpu=arm1176j-s -mattr=+strict-align | FileCheck %s --check-prefix=STRICT-ALIGN ; RUN: llc < %s -mtriple=armv6k-none-linux-gnueabi -mcpu=arm1176j-s | FileCheck %s --check-prefix=NO-STRICT-ALIGN ; ARMv6m @@ -222,6 +223,8 @@ ; RUN: llc < %s -mtriple=thumbv8-none-none-eabi -mcpu=cortex-m33 | FileCheck %s --check-prefix=NO-STRICT-ALIGN ; RUN: llc < %s -mtriple=thumbv8-none-none-eabi -mcpu=cortex-m33 -mattr=+strict-align | FileCheck %s --check-prefix=STRICT-ALIGN +; CPU-SUPPORTED-NOT: is not a recognized processor for this target + ; XSCALE: .eabi_attribute 6, 5 ; XSCALE: .eabi_attribute 8, 1 ; XSCALE: .eabi_attribute 9, 1 diff --git a/test/CodeGen/ARM/load-arm.ll b/test/CodeGen/ARM/load-arm.ll new file mode 100644 index 0000000000000..3807424ece81a --- /dev/null +++ b/test/CodeGen/ARM/load-arm.ll @@ -0,0 +1,28 @@ +; RUN: llc -mtriple=arm %s -o - | FileCheck %s +; RUN: llc -mtriple=thumbv7 %s -o - | FileCheck %s + +; We ended up feeding a deleted node back to TableGen when we converted "Off * +; 410" into "(Off * 205) << 1", where the multiplication already existed in the +; DAG. + +; CHECK-LABEL: addrmode_cse_mutation: +; CHECK: {{mul|muls}} [[OFFSET:r[0-9]+]], {{r[0-9]+}}, {{r[0-9]+}} +; CHECK: {{ldrb|ldrb.w}} {{r[0-9]+}}, [r0, [[OFFSET]], lsl #3] +define i32 @addrmode_cse_mutation(i8* %base, i32 %count) { + %offset = mul i32 %count, 277288 + %ptr = getelementptr i8, i8* %base, i32 %offset + %val = load volatile i8, i8* %ptr + %res = mul i32 %count, 34661 + ret i32 %res +} + +; CHECK-LABEL: addrmode_cse_multi_use: +; CHECK-NOT: {{ldrb|ldrb.w}} {{r[0-9]+}}, [{{r[0-9]+}}, {{r[0-9]+}}, lsl #3] +define i32 @addrmode_cse_multi_use(i8* %base, i32 %count) { + %offset = mul i32 %count, 277288 + %ptr = getelementptr i8, i8* %base, i32 %offset + %val = load volatile i8, i8* %ptr + %res = mul i32 %count, 34661 + %res.1 = add i32 %res, %offset + ret i32 %res.1 +} diff --git a/test/CodeGen/AVR/brind.ll b/test/CodeGen/AVR/brind.ll index f92038d108294..ec8262e84a952 100644 --- a/test/CodeGen/AVR/brind.ll +++ b/test/CodeGen/AVR/brind.ll @@ -4,8 +4,6 @@ define i8 @brind(i8 %p) { ; CHECK-LABEL: brind: -; CHECK: ld r30 -; CHECK: ldd r31 ; CHECK: ijmp entry: %idxprom = sext i8 %p to i16 diff --git a/test/CodeGen/AVR/dynalloca.ll b/test/CodeGen/AVR/dynalloca.ll index 13f503015f9f3..6aa776e2de6f9 100644 --- a/test/CodeGen/AVR/dynalloca.ll +++ b/test/CodeGen/AVR/dynalloca.ll @@ -69,9 +69,9 @@ define void @dynalloca2(i16 %x) { ; SP restore ; CHECK: in r0, 63 ; CHECK-NEXT: cli -; CHECK-NEXT: out 62, r29 +; CHECK-NEXT: out 62, r7 ; CHECK-NEXT: out 63, r0 -; CHECK-NEXT: out 61, r28 +; CHECK-NEXT: out 61, r6 %vla = alloca i16, i16 %x call void @foo2(i16* %vla, i64 0, i64 0, i64 0) ret void diff --git a/test/CodeGen/AVR/inline-asm/inline-asm.ll b/test/CodeGen/AVR/inline-asm/inline-asm.ll index 88d0c3af2e885..26f90806781ea 100644 --- a/test/CodeGen/AVR/inline-asm/inline-asm.ll +++ b/test/CodeGen/AVR/inline-asm/inline-asm.ll @@ -1,4 +1,5 @@ ; RUN: llc < %s -march=avr -mattr=movw -no-integrated-as | FileCheck %s +; XFAIL: * ; CHECK-LABEL: no_operands: define void @no_operands() { diff --git a/test/CodeGen/BPF/reloc.ll b/test/CodeGen/BPF/reloc.ll new file mode 100644 index 0000000000000..75dbebf311e3d --- /dev/null +++ b/test/CodeGen/BPF/reloc.ll @@ -0,0 +1,43 @@ +; RUN: llc -march=bpfel -filetype=obj < %s | llvm-objdump -r - | FileCheck --check-prefix=CHECK-RELOC %s + +%struct.bpf_context = type { i64, i64, i64, i64, i64, i64, i64 } +%struct.sk_buff = type { i64, i64, i64, i64, i64, i64, i64 } +%struct.net_device = type { i64, i64, i64, i64, i64, i64, i64 } + +@bpf_prog1.devname = private unnamed_addr constant [3 x i8] c"lo\00", align 1 +@bpf_prog1.fmt = private unnamed_addr constant [15 x i8] c"skb %x dev %x\0A\00", align 1 + +; Function Attrs: norecurse +define i32 @bpf_prog1(%struct.bpf_context* nocapture %ctx) #0 section "events/net/netif_receive_skb" { + %devname = alloca [3 x i8], align 1 + %fmt = alloca [15 x i8], align 1 + %1 = getelementptr inbounds [3 x i8], [3 x i8]* %devname, i64 0, i64 0 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %1, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @bpf_prog1.devname, i64 0, i64 0), i64 3, i32 1, i1 false) + %2 = getelementptr inbounds %struct.bpf_context, %struct.bpf_context* %ctx, i64 0, i32 0 + %3 = load i64, i64* %2, align 8 + %4 = inttoptr i64 %3 to %struct.sk_buff* + %5 = getelementptr inbounds %struct.sk_buff, %struct.sk_buff* %4, i64 0, i32 2 + %6 = bitcast i64* %5 to i8* + %7 = call i8* inttoptr (i64 4 to i8* (i8*)*)(i8* %6) #1 + %8 = call i32 inttoptr (i64 9 to i32 (i8*, i8*, i32)*)(i8* %7, i8* %1, i32 2) #1 + %9 = icmp eq i32 %8, 0 + br i1 %9, label %10, label %13 + +; <label>:10 ; preds = %0 + %11 = getelementptr inbounds [15 x i8], [15 x i8]* %fmt, i64 0, i64 0 + call void @llvm.memcpy.p0i8.p0i8.i64(i8* %11, i8* getelementptr inbounds ([15 x i8], [15 x i8]* @bpf_prog1.fmt, i64 0, i64 0), i64 15, i32 1, i1 false) + %12 = call i32 (i8*, i32, ...) inttoptr (i64 11 to i32 (i8*, i32, ...)*)(i8* %11, i32 15, %struct.sk_buff* %4, i8* %7) #1 + br label %13 + +; <label>:13 ; preds = %10, %0 + ret i32 0 + +; CHECK-RELOC: file format ELF64-BPF +; CHECK-RELOC: RELOCATION RECORDS FOR [.rel.eh_frame]: +; CHECK-RELOC: R_BPF_64_64 events/net/netif_receive_skb +} + +; Function Attrs: nounwind +declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) #1 + +attributes #0 = { norecurse } diff --git a/test/CodeGen/Hexagon/adjust-latency-stackST.ll b/test/CodeGen/Hexagon/adjust-latency-stackST.ll new file mode 100644 index 0000000000000..915db91635f1a --- /dev/null +++ b/test/CodeGen/Hexagon/adjust-latency-stackST.ll @@ -0,0 +1,81 @@ +; RUN: llc -march=hexagon -disable-post-ra < %s | FileCheck %s + +; Make sure that if there's only one store to the stack, it gets packetized +; with allocframe as there's a latency of 2 cycles between allocframe and +; the following store if not in the same packet. + +; CHECK: { +; CHECK: memd(r29 +; CHECK-NOT: { +; CHECK: allocframe +; CHECK: } +; CHECK: = memw(gp+#G) + +%struct.0 = type { %struct.0*, i32, %struct.2 } +%struct.1 = type { i32, i32, [31 x i8] } +%struct.2 = type { %struct.1 } + +@G = common global %struct.0* null, align 4 + +define i32 @test(%struct.0* nocapture %a0) #0 { +b1: + %v2 = alloca %struct.0*, align 4 + %v3 = bitcast %struct.0** %v2 to i8* + %v4 = getelementptr inbounds %struct.0, %struct.0* %a0, i32 0, i32 0 + %v5 = load %struct.0*, %struct.0** %v4, align 4 + store %struct.0* %v5, %struct.0** %v2, align 4 + %v6 = bitcast %struct.0* %v5 to i8* + %v7 = load i8*, i8** bitcast (%struct.0** @G to i8**), align 4 + tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* %v6, i8* %v7, i32 48, i32 4, i1 false) + %v8 = getelementptr inbounds %struct.0, %struct.0* %a0, i32 0, i32 2, i32 0, i32 1 + store i32 5, i32* %v8, align 4 + %v9 = getelementptr inbounds %struct.0, %struct.0* %v5, i32 0, i32 2, i32 0, i32 1 + store i32 5, i32* %v9, align 4 + %v10 = bitcast %struct.0* %a0 to i32* + %v11 = load i32, i32* %v10, align 4 + %v12 = bitcast %struct.0* %v5 to i32* + store i32 %v11, i32* %v12, align 4 + %v13 = call i32 bitcast (i32 (...)* @f0 to i32 (%struct.0**)*)(%struct.0** nonnull %v2) + %v14 = load %struct.0*, %struct.0** %v2, align 4 + %v15 = getelementptr inbounds %struct.0, %struct.0* %v14, i32 0, i32 1 + %v16 = load i32, i32* %v15, align 4 + %v17 = icmp eq i32 %v16, 0 + br i1 %v17, label %b18, label %b32 + +b18: ; preds = %b1 + %v19 = bitcast %struct.0** %v2 to i32** + %v20 = getelementptr inbounds %struct.0, %struct.0* %v14, i32 0, i32 2, i32 0, i32 1 + store i32 6, i32* %v20, align 4 + %v21 = getelementptr inbounds %struct.0, %struct.0* %a0, i32 0, i32 2, i32 0, i32 0 + %v22 = load i32, i32* %v21, align 4 + %v23 = getelementptr inbounds %struct.0, %struct.0* %v14, i32 0, i32 2, i32 0, i32 0 + %v24 = call i32 bitcast (i32 (...)* @f1 to i32 (i32, i32*)*)(i32 %v22, i32* %v23) + %v25 = load i32*, i32** bitcast (%struct.0** @G to i32**), align 4 + %v26 = load i32, i32* %v25, align 4 + %v27 = load i32*, i32** %v19, align 4 + store i32 %v26, i32* %v27, align 4 + %v28 = load %struct.0*, %struct.0** %v2, align 4 + %v29 = getelementptr inbounds %struct.0, %struct.0* %v28, i32 0, i32 2, i32 0, i32 1 + %v30 = load i32, i32* %v29, align 4 + %v31 = call i32 bitcast (i32 (...)* @f2 to i32 (i32, i32, i32*)*)(i32 %v30, i32 10, i32* %v29) + br label %b36 + +b32: ; preds = %b1 + %v33 = bitcast %struct.0* %a0 to i8** + %v34 = load i8*, i8** %v33, align 4 + %v35 = bitcast %struct.0* %a0 to i8* + call void @llvm.memcpy.p0i8.p0i8.i32(i8* %v35, i8* %v34, i32 48, i32 4, i1 false) + br label %b36 + +b36: ; preds = %b32, %b18 + ret i32 undef +} + +declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i1) #1 + +declare i32 @f0(...) #0 +declare i32 @f1(...) #0 +declare i32 @f2(...) #0 + +attributes #0 = { nounwind } +attributes #1 = { argmemonly nounwind } diff --git a/test/CodeGen/Hexagon/multi-cycle.ll b/test/CodeGen/Hexagon/multi-cycle.ll new file mode 100644 index 0000000000000..fc021821af388 --- /dev/null +++ b/test/CodeGen/Hexagon/multi-cycle.ll @@ -0,0 +1,103 @@ +; RUN: llc -march=hexagon -O2 < %s | FileCheck %s + +; CHECK: v{{[0-9]+}}.h{{ *}}={{ *}}vadd(v{{[0-9]+}}.h,v{{[0-9]+}}.h) +; CHECK: } +; CHECK: { +; CHECK: v{{[0-9]+}}{{ *}}={{ *}}valign(v{{[0-9]+}},v{{[0-9]+}},r{{[0-9]+}}) +; CHECK: } +; CHECK: { +; CHECK: v{{[0-9]+}}{{ *}}={{ *}}valign(v{{[0-9]+}},v{{[0-9]+}},r{{[0-9]+}}) + +target triple = "hexagon" + +@ZERO = global <16 x i32> zeroinitializer, align 64 + +define void @fred(i16* nocapture readonly %a0, i32 %a1, i32 %a2, i16* nocapture %a3) #0 { +b4: + %v5 = bitcast i16* %a0 to <16 x i32>* + %v6 = getelementptr inbounds i16, i16* %a0, i32 %a1 + %v7 = bitcast i16* %v6 to <16 x i32>* + %v8 = mul nsw i32 %a1, 2 + %v9 = getelementptr inbounds i16, i16* %a0, i32 %v8 + %v10 = bitcast i16* %v9 to <16 x i32>* + %v11 = load <16 x i32>, <16 x i32>* %v5, align 64, !tbaa !1 + %v12 = load <16 x i32>, <16 x i32>* %v7, align 64, !tbaa !1 + %v13 = load <16 x i32>, <16 x i32>* %v10, align 64, !tbaa !1 + %v14 = load <16 x i32>, <16 x i32>* @ZERO, align 64, !tbaa !1 + %v15 = tail call <16 x i32> @llvm.hexagon.V6.vsubh(<16 x i32> %v14, <16 x i32> %v14) + %v16 = sdiv i32 %a2, 32 + %v17 = icmp sgt i32 %a2, 31 + br i1 %v17, label %b18, label %b66 + +b18: ; preds = %b4 + %v19 = add i32 %v8, 32 + %v20 = add i32 %a1, 32 + %v21 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v12, <16 x i32> %v12) + %v22 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v11, <16 x i32> %v13) + %v23 = getelementptr inbounds i16, i16* %a0, i32 %v19 + %v24 = getelementptr inbounds i16, i16* %a0, i32 %v20 + %v25 = getelementptr inbounds i16, i16* %a0, i32 32 + %v26 = tail call <16 x i32> @llvm.hexagon.V6.vsubh(<16 x i32> %v11, <16 x i32> %v13) + %v27 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v22, <16 x i32> %v21) + %v28 = bitcast i16* %v23 to <16 x i32>* + %v29 = bitcast i16* %v24 to <16 x i32>* + %v30 = bitcast i16* %v25 to <16 x i32>* + %v31 = bitcast i16* %a3 to <16 x i32>* + br label %b32 + +b32: ; preds = %b32, %b18 + %v33 = phi i32 [ 0, %b18 ], [ %v63, %b32 ] + %v34 = phi <16 x i32>* [ %v31, %b18 ], [ %v62, %b32 ] + %v35 = phi <16 x i32>* [ %v28, %b18 ], [ %v46, %b32 ] + %v36 = phi <16 x i32>* [ %v29, %b18 ], [ %v44, %b32 ] + %v37 = phi <16 x i32>* [ %v30, %b18 ], [ %v42, %b32 ] + %v38 = phi <16 x i32> [ %v15, %b18 ], [ %v39, %b32 ] + %v39 = phi <16 x i32> [ %v26, %b18 ], [ %v56, %b32 ] + %v40 = phi <16 x i32> [ %v27, %b18 ], [ %v51, %b32 ] + %v41 = phi <16 x i32> [ %v15, %b18 ], [ %v40, %b32 ] + %v42 = getelementptr inbounds <16 x i32>, <16 x i32>* %v37, i32 1 + %v43 = load <16 x i32>, <16 x i32>* %v37, align 64, !tbaa !1 + %v44 = getelementptr inbounds <16 x i32>, <16 x i32>* %v36, i32 1 + %v45 = load <16 x i32>, <16 x i32>* %v36, align 64, !tbaa !1 + %v46 = getelementptr inbounds <16 x i32>, <16 x i32>* %v35, i32 1 + %v47 = load <16 x i32>, <16 x i32>* %v35, align 64, !tbaa !1 + %v48 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v43, <16 x i32> %v47) + %v49 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v45, <16 x i32> %v45) + %v50 = tail call <16 x i32> @llvm.hexagon.V6.valignb(<16 x i32> %v40, <16 x i32> %v41, i32 62) + %v51 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v48, <16 x i32> %v49) + %v52 = tail call <16 x i32> @llvm.hexagon.V6.valignb(<16 x i32> %v51, <16 x i32> %v40, i32 2) + %v53 = tail call <16 x i32> @llvm.hexagon.V6.vabsdiffh(<16 x i32> %v50, <16 x i32> %v52) + %v54 = getelementptr inbounds <16 x i32>, <16 x i32>* %v34, i32 1 + store <16 x i32> %v53, <16 x i32>* %v34, align 64, !tbaa !1 + %v55 = tail call <16 x i32> @llvm.hexagon.V6.valignb(<16 x i32> %v39, <16 x i32> %v38, i32 62) + %v56 = tail call <16 x i32> @llvm.hexagon.V6.vsubh(<16 x i32> %v43, <16 x i32> %v47) + %v57 = tail call <16 x i32> @llvm.hexagon.V6.valignb(<16 x i32> %v56, <16 x i32> %v39, i32 2) + %v58 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v39, <16 x i32> %v39) + %v59 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v58, <16 x i32> %v55) + %v60 = tail call <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32> %v59, <16 x i32> %v57) + %v61 = tail call <16 x i32> @llvm.hexagon.V6.vabsh(<16 x i32> %v60) + %v62 = getelementptr inbounds <16 x i32>, <16 x i32>* %v34, i32 2 + store <16 x i32> %v61, <16 x i32>* %v54, align 64, !tbaa !1 + %v63 = add nsw i32 %v33, 1 + %v64 = icmp slt i32 %v63, %v16 + br i1 %v64, label %b32, label %b65 + +b65: ; preds = %b32 + br label %b66 + +b66: ; preds = %b65, %b4 + ret void +} + +declare <16 x i32> @llvm.hexagon.V6.vaddh(<16 x i32>, <16 x i32>) #1 +declare <16 x i32> @llvm.hexagon.V6.vsubh(<16 x i32>, <16 x i32>) #1 +declare <16 x i32> @llvm.hexagon.V6.valignb(<16 x i32>, <16 x i32>, i32) #1 +declare <16 x i32> @llvm.hexagon.V6.vabsdiffh(<16 x i32>, <16 x i32>) #1 +declare <16 x i32> @llvm.hexagon.V6.vabsh(<16 x i32>) #1 + +attributes #0 = { nounwind "target-cpu"="hexagonv60" "target-features"="+hvx" } +attributes #1 = { nounwind readnone } + +!1 = !{!2, !2, i64 0} +!2 = !{!"omnipotent char", !3, i64 0} +!3 = !{!"Simple C/C++ TBAA"} diff --git a/test/CodeGen/Hexagon/plt-rel.ll b/test/CodeGen/Hexagon/plt-rel.ll new file mode 100644 index 0000000000000..1d38cf32b8860 --- /dev/null +++ b/test/CodeGen/Hexagon/plt-rel.ll @@ -0,0 +1,37 @@ +; RUN: llc -march=hexagon -relocation-model=pic -mattr=+long-calls < %s | FileCheck --check-prefix=CHECK-LONG %s +; RUN: llc -march=hexagon -relocation-model=pic < %s | FileCheck %s + +; CHECK-LONG: call ##_ZL13g_usr1_called@GDPLT +; CHECK-LONG-NOT: call _ZL13g_usr1_called@GDPLT +; CHECK: call _ZL13g_usr1_called@GDPLT +; CHECK-NOT: call ##_ZL13g_usr1_called@GDPLT + + +target triple = "hexagon" + +@_ZL13g_usr1_called = internal thread_local global i32 0, align 4 + +; Function Attrs: norecurse nounwind +define void @_Z14SigUsr1Handleri(i32) local_unnamed_addr #0 { +entry: + store volatile i32 1, i32* @_ZL13g_usr1_called, align 4 + ret void +} + +; Function Attrs: norecurse nounwind +define zeroext i1 @_Z27CheckForMonitorCancellationv() local_unnamed_addr #0 { +entry: + %0 = load volatile i32, i32* @_ZL13g_usr1_called, align 4 + %tobool = icmp eq i32 %0, 0 + br i1 %tobool, label %return, label %if.then + +if.then: ; preds = %entry + store volatile i32 0, i32* @_ZL13g_usr1_called, align 4 + br label %return + +return: ; preds = %entry, %if.then + %.sink = phi i1 [ true, %if.then ], [ false, %entry ] + ret i1 %.sink +} + +attributes #0 = { norecurse nounwind "target-cpu"="hexagonv60" "target-features"="+hvx" } diff --git a/test/CodeGen/PowerPC/shift_mask.ll b/test/CodeGen/PowerPC/shift_mask.ll index 91226a336721e..e9ca9b0bdf022 100644 --- a/test/CodeGen/PowerPC/shift_mask.ll +++ b/test/CodeGen/PowerPC/shift_mask.ll @@ -49,8 +49,6 @@ define i64 @test003(i64 %a, i64 %b) { define <16 x i8> @test010(<16 x i8> %a, <16 x i8> %b) { ; CHECK-LABEL: test010: ; CHECK: # BB#0: -; CHECK-NEXT: vspltisb 4, 7 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vslb 2, 2, 3 ; CHECK-NEXT: blr %rem = and <16 x i8> %b, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7> @@ -61,8 +59,6 @@ define <16 x i8> @test010(<16 x i8> %a, <16 x i8> %b) { define <8 x i16> @test011(<8 x i16> %a, <8 x i16> %b) { ; CHECK-LABEL: test011: ; CHECK: # BB#0: -; CHECK-NEXT: vspltish 4, 15 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vslh 2, 2, 3 ; CHECK-NEXT: blr %rem = and <8 x i16> %b, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> @@ -73,10 +69,6 @@ define <8 x i16> @test011(<8 x i16> %a, <8 x i16> %b) { define <4 x i32> @test012(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: test012: ; CHECK: # BB#0: -; CHECK-NEXT: vspltisw 4, -16 -; CHECK-NEXT: vspltisw 5, 15 -; CHECK-NEXT: vsubuwm 4, 5, 4 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vslw 2, 2, 3 ; CHECK-NEXT: blr %rem = and <4 x i32> %b, <i32 31, i32 31, i32 31, i32 31> @@ -87,11 +79,6 @@ define <4 x i32> @test012(<4 x i32> %a, <4 x i32> %b) { define <2 x i64> @test013(<2 x i64> %a, <2 x i64> %b) { ; CHECK-LABEL: test013: ; CHECK: # BB#0: -; CHECK-NEXT: addis 3, 2, .LCPI7_0@toc@ha -; CHECK-NEXT: addi 3, 3, .LCPI7_0@toc@l -; CHECK-NEXT: lxvd2x 0, 0, 3 -; CHECK-NEXT: xxswapd 36, 0 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsld 2, 2, 3 ; CHECK-NEXT: blr %rem = and <2 x i64> %b, <i64 63, i64 63> @@ -148,8 +135,6 @@ define i64 @test103(i64 %a, i64 %b) { define <16 x i8> @test110(<16 x i8> %a, <16 x i8> %b) { ; CHECK-LABEL: test110: ; CHECK: # BB#0: -; CHECK-NEXT: vspltisb 4, 7 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsrb 2, 2, 3 ; CHECK-NEXT: blr %rem = and <16 x i8> %b, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7> @@ -160,8 +145,6 @@ define <16 x i8> @test110(<16 x i8> %a, <16 x i8> %b) { define <8 x i16> @test111(<8 x i16> %a, <8 x i16> %b) { ; CHECK-LABEL: test111: ; CHECK: # BB#0: -; CHECK-NEXT: vspltish 4, 15 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsrh 2, 2, 3 ; CHECK-NEXT: blr %rem = and <8 x i16> %b, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> @@ -172,10 +155,6 @@ define <8 x i16> @test111(<8 x i16> %a, <8 x i16> %b) { define <4 x i32> @test112(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: test112: ; CHECK: # BB#0: -; CHECK-NEXT: vspltisw 4, -16 -; CHECK-NEXT: vspltisw 5, 15 -; CHECK-NEXT: vsubuwm 4, 5, 4 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsrw 2, 2, 3 ; CHECK-NEXT: blr %rem = and <4 x i32> %b, <i32 31, i32 31, i32 31, i32 31> @@ -186,11 +165,6 @@ define <4 x i32> @test112(<4 x i32> %a, <4 x i32> %b) { define <2 x i64> @test113(<2 x i64> %a, <2 x i64> %b) { ; CHECK-LABEL: test113: ; CHECK: # BB#0: -; CHECK-NEXT: addis 3, 2, .LCPI15_0@toc@ha -; CHECK-NEXT: addi 3, 3, .LCPI15_0@toc@l -; CHECK-NEXT: lxvd2x 0, 0, 3 -; CHECK-NEXT: xxswapd 36, 0 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsrd 2, 2, 3 ; CHECK-NEXT: blr %rem = and <2 x i64> %b, <i64 63, i64 63> @@ -247,8 +221,6 @@ define i64 @test203(i64 %a, i64 %b) { define <16 x i8> @test210(<16 x i8> %a, <16 x i8> %b) { ; CHECK-LABEL: test210: ; CHECK: # BB#0: -; CHECK-NEXT: vspltisb 4, 7 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsrab 2, 2, 3 ; CHECK-NEXT: blr %rem = and <16 x i8> %b, <i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7, i8 7> @@ -259,8 +231,6 @@ define <16 x i8> @test210(<16 x i8> %a, <16 x i8> %b) { define <8 x i16> @test211(<8 x i16> %a, <8 x i16> %b) { ; CHECK-LABEL: test211: ; CHECK: # BB#0: -; CHECK-NEXT: vspltish 4, 15 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsrah 2, 2, 3 ; CHECK-NEXT: blr %rem = and <8 x i16> %b, <i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15, i16 15> @@ -271,10 +241,6 @@ define <8 x i16> @test211(<8 x i16> %a, <8 x i16> %b) { define <4 x i32> @test212(<4 x i32> %a, <4 x i32> %b) { ; CHECK-LABEL: test212: ; CHECK: # BB#0: -; CHECK-NEXT: vspltisw 4, -16 -; CHECK-NEXT: vspltisw 5, 15 -; CHECK-NEXT: vsubuwm 4, 5, 4 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsraw 2, 2, 3 ; CHECK-NEXT: blr %rem = and <4 x i32> %b, <i32 31, i32 31, i32 31, i32 31> @@ -285,11 +251,6 @@ define <4 x i32> @test212(<4 x i32> %a, <4 x i32> %b) { define <2 x i64> @test213(<2 x i64> %a, <2 x i64> %b) { ; CHECK-LABEL: test213: ; CHECK: # BB#0: -; CHECK-NEXT: addis 3, 2, .LCPI23_0@toc@ha -; CHECK-NEXT: addi 3, 3, .LCPI23_0@toc@l -; CHECK-NEXT: lxvd2x 0, 0, 3 -; CHECK-NEXT: xxswapd 36, 0 -; CHECK-NEXT: xxland 35, 35, 36 ; CHECK-NEXT: vsrad 2, 2, 3 ; CHECK-NEXT: blr %rem = and <2 x i64> %b, <i64 63, i64 63> diff --git a/test/CodeGen/X86/addcarry.ll b/test/CodeGen/X86/addcarry.ll index 6fc07cd84deaf..5e95cd832789b 100644 --- a/test/CodeGen/X86/addcarry.ll +++ b/test/CodeGen/X86/addcarry.ll @@ -190,9 +190,9 @@ entry: define i64 @shiftadd(i64 %a, i64 %b, i64 %c, i64 %d) { ; CHECK-LABEL: shiftadd: ; CHECK: # BB#0: # %entry -; CHECK-NEXT: leaq (%rdx,%rcx), %rax ; CHECK-NEXT: addq %rsi, %rdi -; CHECK-NEXT: adcq $0, %rax +; CHECK-NEXT: adcq %rcx, %rdx +; CHECK-NEXT: movq %rdx, %rax ; CHECK-NEXT: retq entry: %0 = zext i64 %a to i128 diff --git a/test/CodeGen/X86/lwp-intrinsics-x86_64.ll b/test/CodeGen/X86/lwp-intrinsics-x86_64.ll new file mode 100644 index 0000000000000..9ee95267fc33a --- /dev/null +++ b/test/CodeGen/X86/lwp-intrinsics-x86_64.ll @@ -0,0 +1,49 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+lwp | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=bdver1 | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=bdver2 | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=bdver3 | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=bdver4 | FileCheck %s --check-prefix=X64 + +define i8 @test_lwpins64_rri(i64 %a0, i32 %a1) nounwind { +; X64-LABEL: test_lwpins64_rri: +; X64: # BB#0: +; X64-NEXT: lwpins $-1985229329, %esi, %rdi # imm = 0x89ABCDEF +; X64-NEXT: setb %al +; X64-NEXT: retq + %1 = tail call i8 @llvm.x86.lwpins64(i64 %a0, i32 %a1, i32 2309737967) + ret i8 %1 +} + +define i8 @test_lwpins64_rmi(i64 %a0, i32 *%p1) nounwind { +; X64-LABEL: test_lwpins64_rmi: +; X64: # BB#0: +; X64-NEXT: lwpins $1985229328, (%rsi), %rdi # imm = 0x76543210 +; X64-NEXT: setb %al +; X64-NEXT: retq + %a1 = load i32, i32 *%p1 + %1 = tail call i8 @llvm.x86.lwpins64(i64 %a0, i32 %a1, i32 1985229328) + ret i8 %1 +} + +define void @test_lwpval64_rri(i64 %a0, i32 %a1) nounwind { +; X64-LABEL: test_lwpval64_rri: +; X64: # BB#0: +; X64-NEXT: lwpval $-19088744, %esi, %rdi # imm = 0xFEDCBA98 +; X64-NEXT: retq + tail call void @llvm.x86.lwpval64(i64 %a0, i32 %a1, i32 4275878552) + ret void +} + +define void @test_lwpval64_rmi(i64 %a0, i32 *%p1) nounwind { +; X64-LABEL: test_lwpval64_rmi: +; X64: # BB#0: +; X64-NEXT: lwpval $305419896, (%rsi), %rdi # imm = 0x12345678 +; X64-NEXT: retq + %a1 = load i32, i32 *%p1 + tail call void @llvm.x86.lwpval64(i64 %a0, i32 %a1, i32 305419896) + ret void +} + +declare i8 @llvm.x86.lwpins64(i64, i32, i32) nounwind +declare void @llvm.x86.lwpval64(i64, i32, i32) nounwind diff --git a/test/CodeGen/X86/lwp-intrinsics.ll b/test/CodeGen/X86/lwp-intrinsics.ll new file mode 100644 index 0000000000000..c949bc806083e --- /dev/null +++ b/test/CodeGen/X86/lwp-intrinsics.ll @@ -0,0 +1,121 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i686-unknown -mattr=+lwp | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=i686-unknown -mcpu=bdver1 | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=i686-unknown -mcpu=bdver2 | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=i686-unknown -mcpu=bdver3 | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=i686-unknown -mcpu=bdver4 | FileCheck %s --check-prefix=X86 +; RUN: llc < %s -mtriple=x86_64-unknown -mattr=+lwp | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=bdver1 | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=bdver2 | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=bdver3 | FileCheck %s --check-prefix=X64 +; RUN: llc < %s -mtriple=x86_64-unknown -mcpu=bdver4 | FileCheck %s --check-prefix=X64 + +define void @test_llwpcb(i8 *%a0) nounwind { +; X86-LABEL: test_llwpcb: +; X86: # BB#0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: llwpcb %eax +; X86-NEXT: retl +; +; X64-LABEL: test_llwpcb: +; X64: # BB#0: +; X64-NEXT: llwpcb %rdi +; X64-NEXT: retq + tail call void @llvm.x86.llwpcb(i8 *%a0) + ret void +} + +define i8* @test_slwpcb(i8 *%a0) nounwind { +; X86-LABEL: test_slwpcb: +; X86: # BB#0: +; X86-NEXT: slwpcb %eax +; X86-NEXT: retl +; +; X64-LABEL: test_slwpcb: +; X64: # BB#0: +; X64-NEXT: slwpcb %rax +; X64-NEXT: retq + %1 = tail call i8* @llvm.x86.slwpcb() + ret i8 *%1 +} + +define i8 @test_lwpins32_rri(i32 %a0, i32 %a1) nounwind { +; X86-LABEL: test_lwpins32_rri: +; X86: # BB#0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: addl %ecx, %ecx +; X86-NEXT: lwpins $-1985229329, %ecx, %eax # imm = 0x89ABCDEF +; X86-NEXT: setb %al +; X86-NEXT: retl +; +; X64-LABEL: test_lwpins32_rri: +; X64: # BB#0: +; X64-NEXT: addl %esi, %esi +; X64-NEXT: lwpins $-1985229329, %esi, %edi # imm = 0x89ABCDEF +; X64-NEXT: setb %al +; X64-NEXT: retq + %1 = add i32 %a1, %a1 + %2 = tail call i8 @llvm.x86.lwpins32(i32 %a0, i32 %1, i32 2309737967) + ret i8 %2 +} + +define i8 @test_lwpins32_rmi(i32 %a0, i32 *%p1) nounwind { +; X86-LABEL: test_lwpins32_rmi: +; X86: # BB#0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: lwpins $1985229328, (%eax), %ecx # imm = 0x76543210 +; X86-NEXT: setb %al +; X86-NEXT: retl +; +; X64-LABEL: test_lwpins32_rmi: +; X64: # BB#0: +; X64-NEXT: lwpins $1985229328, (%rsi), %edi # imm = 0x76543210 +; X64-NEXT: setb %al +; X64-NEXT: retq + %a1 = load i32, i32 *%p1 + %1 = tail call i8 @llvm.x86.lwpins32(i32 %a0, i32 %a1, i32 1985229328) + ret i8 %1 +} + +define void @test_lwpval32_rri(i32 %a0, i32 %a1) nounwind { +; X86-LABEL: test_lwpval32_rri: +; X86: # BB#0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: addl %ecx, %ecx +; X86-NEXT: lwpval $-19088744, %ecx, %eax # imm = 0xFEDCBA98 +; X86-NEXT: retl +; +; X64-LABEL: test_lwpval32_rri: +; X64: # BB#0: +; X64-NEXT: addl %esi, %esi +; X64-NEXT: lwpval $-19088744, %esi, %edi # imm = 0xFEDCBA98 +; X64-NEXT: retq + %1 = add i32 %a1, %a1 + tail call void @llvm.x86.lwpval32(i32 %a0, i32 %1, i32 4275878552) + ret void +} + +define void @test_lwpval32_rmi(i32 %a0, i32 *%p1) nounwind { +; X86-LABEL: test_lwpval32_rmi: +; X86: # BB#0: +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx +; X86-NEXT: lwpval $305419896, (%eax), %ecx # imm = 0x12345678 +; X86-NEXT: retl +; +; X64-LABEL: test_lwpval32_rmi: +; X64: # BB#0: +; X64-NEXT: lwpval $305419896, (%rsi), %edi # imm = 0x12345678 +; X64-NEXT: retq + %a1 = load i32, i32 *%p1 + tail call void @llvm.x86.lwpval32(i32 %a0, i32 %a1, i32 305419896) + ret void +} + +declare void @llvm.x86.llwpcb(i8*) nounwind +declare i8* @llvm.x86.slwpcb() nounwind +declare i8 @llvm.x86.lwpins32(i32, i32, i32) nounwind +declare void @llvm.x86.lwpval32(i32, i32, i32) nounwind diff --git a/test/CodeGen/X86/masked_gather_scatter.ll b/test/CodeGen/X86/masked_gather_scatter.ll index 1a15cab97e2e5..29a662fb217e9 100644 --- a/test/CodeGen/X86/masked_gather_scatter.ll +++ b/test/CodeGen/X86/masked_gather_scatter.ll @@ -54,13 +54,13 @@ define <16 x float> @test1(float* %base, <16 x i32> %ind) { %sext_ind = sext <16 x i32> %ind to <16 x i64> %gep.random = getelementptr float, <16 x float*> %broadcast.splat, <16 x i64> %sext_ind - %res = call <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) + %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) ret <16 x float>%res } -declare <16 x i32> @llvm.masked.gather.v16i32(<16 x i32*>, i32, <16 x i1>, <16 x i32>) -declare <16 x float> @llvm.masked.gather.v16f32(<16 x float*>, i32, <16 x i1>, <16 x float>) -declare <8 x i32> @llvm.masked.gather.v8i32(<8 x i32*> , i32, <8 x i1> , <8 x i32> ) +declare <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*>, i32, <16 x i1>, <16 x i32>) +declare <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*>, i32, <16 x i1>, <16 x float>) +declare <8 x i32> @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*> , i32, <8 x i1> , <8 x i32> ) ; SCALAR-LABEL: test2 @@ -111,7 +111,7 @@ define <16 x float> @test2(float* %base, <16 x i32> %ind, i16 %mask) { %sext_ind = sext <16 x i32> %ind to <16 x i64> %gep.random = getelementptr float, <16 x float*> %broadcast.splat, <16 x i64> %sext_ind %imask = bitcast i16 %mask to <16 x i1> - %res = call <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %gep.random, i32 4, <16 x i1> %imask, <16 x float>undef) + %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> %imask, <16 x float>undef) ret <16 x float> %res } @@ -152,7 +152,7 @@ define <16 x i32> @test3(i32* %base, <16 x i32> %ind, i16 %mask) { %sext_ind = sext <16 x i32> %ind to <16 x i64> %gep.random = getelementptr i32, <16 x i32*> %broadcast.splat, <16 x i64> %sext_ind %imask = bitcast i16 %mask to <16 x i1> - %res = call <16 x i32> @llvm.masked.gather.v16i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>undef) + %res = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>undef) ret <16 x i32> %res } @@ -205,8 +205,8 @@ define <16 x i32> @test4(i32* %base, <16 x i32> %ind, i16 %mask) { %gep.random = getelementptr i32, <16 x i32*> %broadcast.splat, <16 x i32> %ind %imask = bitcast i16 %mask to <16 x i1> - %gt1 = call <16 x i32> @llvm.masked.gather.v16i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>undef) - %gt2 = call <16 x i32> @llvm.masked.gather.v16i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>%gt1) + %gt1 = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>undef) + %gt2 = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %gep.random, i32 4, <16 x i1> %imask, <16 x i32>%gt1) %res = add <16 x i32> %gt1, %gt2 ret <16 x i32> %res } @@ -270,13 +270,13 @@ define void @test5(i32* %base, <16 x i32> %ind, i16 %mask, <16 x i32>%val) { %gep.random = getelementptr i32, <16 x i32*> %broadcast.splat, <16 x i32> %ind %imask = bitcast i16 %mask to <16 x i1> - call void @llvm.masked.scatter.v16i32(<16 x i32>%val, <16 x i32*> %gep.random, i32 4, <16 x i1> %imask) - call void @llvm.masked.scatter.v16i32(<16 x i32>%val, <16 x i32*> %gep.random, i32 4, <16 x i1> %imask) + call void @llvm.masked.scatter.v16i32.v16p0i32(<16 x i32>%val, <16 x i32*> %gep.random, i32 4, <16 x i1> %imask) + call void @llvm.masked.scatter.v16i32.v16p0i32(<16 x i32>%val, <16 x i32*> %gep.random, i32 4, <16 x i1> %imask) ret void } -declare void @llvm.masked.scatter.v8i32(<8 x i32> , <8 x i32*> , i32 , <8 x i1> ) -declare void @llvm.masked.scatter.v16i32(<16 x i32> , <16 x i32*> , i32 , <16 x i1> ) +declare void @llvm.masked.scatter.v8i32.v8p0i32(<8 x i32> , <8 x i32*> , i32 , <8 x i1> ) +declare void @llvm.masked.scatter.v16i32.v16p0i32(<16 x i32> , <16 x i32*> , i32 , <16 x i1> ) ; SCALAR-LABEL: test6 @@ -326,9 +326,9 @@ define <8 x i32> @test6(<8 x i32>%a1, <8 x i32*> %ptr) { ; SKX_32-NEXT: vmovdqa %ymm2, %ymm0 ; SKX_32-NEXT: retl - %a = call <8 x i32> @llvm.masked.gather.v8i32(<8 x i32*> %ptr, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef) + %a = call <8 x i32> @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*> %ptr, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef) - call void @llvm.masked.scatter.v8i32(<8 x i32> %a1, <8 x i32*> %ptr, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>) + call void @llvm.masked.scatter.v8i32.v8p0i32(<8 x i32> %a1, <8 x i32*> %ptr, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>) ret <8 x i32>%a } @@ -384,8 +384,8 @@ define <8 x i32> @test7(i32* %base, <8 x i32> %ind, i8 %mask) { %gep.random = getelementptr i32, <8 x i32*> %broadcast.splat, <8 x i32> %ind %imask = bitcast i8 %mask to <8 x i1> - %gt1 = call <8 x i32> @llvm.masked.gather.v8i32(<8 x i32*> %gep.random, i32 4, <8 x i1> %imask, <8 x i32>undef) - %gt2 = call <8 x i32> @llvm.masked.gather.v8i32(<8 x i32*> %gep.random, i32 4, <8 x i1> %imask, <8 x i32>%gt1) + %gt1 = call <8 x i32> @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*> %gep.random, i32 4, <8 x i1> %imask, <8 x i32>undef) + %gt2 = call <8 x i32> @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*> %gep.random, i32 4, <8 x i1> %imask, <8 x i32>%gt1) %res = add <8 x i32> %gt1, %gt2 ret <8 x i32> %res } @@ -444,8 +444,8 @@ define <16 x i32> @test8(<16 x i32*> %ptr.random, <16 x i32> %ind, i16 %mask) { ; SKX_32-NEXT: retl %imask = bitcast i16 %mask to <16 x i1> - %gt1 = call <16 x i32> @llvm.masked.gather.v16i32(<16 x i32*> %ptr.random, i32 4, <16 x i1> %imask, <16 x i32>undef) - %gt2 = call <16 x i32> @llvm.masked.gather.v16i32(<16 x i32*> %ptr.random, i32 4, <16 x i1> %imask, <16 x i32>%gt1) + %gt1 = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %ptr.random, i32 4, <16 x i1> %imask, <16 x i32>undef) + %gt2 = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %ptr.random, i32 4, <16 x i1> %imask, <16 x i32>%gt1) %res = add <16 x i32> %gt1, %gt2 ret <16 x i32> %res } @@ -522,7 +522,7 @@ entry: %broadcast.splat = shufflevector <8 x %struct.ST*> %broadcast.splatinsert, <8 x %struct.ST*> undef, <8 x i32> zeroinitializer %arrayidx = getelementptr %struct.ST, <8 x %struct.ST*> %broadcast.splat, <8 x i64> %ind1, <8 x i32> <i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2, i32 2>, <8 x i32><i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>, <8 x i32> %ind5, <8 x i64> <i64 13, i64 13, i64 13, i64 13, i64 13, i64 13, i64 13, i64 13> - %res = call <8 x i32 > @llvm.masked.gather.v8i32(<8 x i32*>%arrayidx, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef) + %res = call <8 x i32 > @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*>%arrayidx, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef) ret <8 x i32> %res } @@ -591,7 +591,7 @@ entry: %broadcast.splat = shufflevector <8 x %struct.ST*> %broadcast.splatinsert, <8 x %struct.ST*> undef, <8 x i32> zeroinitializer %arrayidx = getelementptr %struct.ST, <8 x %struct.ST*> %broadcast.splat, <8 x i64> %i1, i32 2, i32 1, <8 x i32> %ind5, i64 13 - %res = call <8 x i32 > @llvm.masked.gather.v8i32(<8 x i32*>%arrayidx, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef) + %res = call <8 x i32 > @llvm.masked.gather.v8i32.v8p0i32(<8 x i32*>%arrayidx, i32 4, <8 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <8 x i32> undef) ret <8 x i32> %res } @@ -632,7 +632,7 @@ define <16 x float> @test11(float* %base, i32 %ind) { %gep.random = getelementptr float, <16 x float*> %broadcast.splat, i32 %ind - %res = call <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) + %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) ret <16 x float>%res } @@ -671,7 +671,7 @@ define <16 x float> @test12(float* %base, <16 x i32> %ind) { %sext_ind = sext <16 x i32> %ind to <16 x i64> %gep.random = getelementptr float, float *%base, <16 x i64> %sext_ind - %res = call <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) + %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) ret <16 x float>%res } @@ -710,7 +710,7 @@ define <16 x float> @test13(float* %base, <16 x i32> %ind) { %sext_ind = sext <16 x i32> %ind to <16 x i64> %gep.random = getelementptr float, float *%base, <16 x i64> %sext_ind - %res = call <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) + %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) ret <16 x float>%res } @@ -772,13 +772,13 @@ define <16 x float> @test14(float* %base, i32 %ind, <16 x float*> %vec) { %gep.random = getelementptr float, <16 x float*> %broadcast.splat, i32 %ind - %res = call <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) + %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float> undef) ret <16 x float>%res } -declare <4 x float> @llvm.masked.gather.v4f32(<4 x float*>, i32, <4 x i1>, <4 x float>) -declare <4 x double> @llvm.masked.gather.v4f64(<4 x double*>, i32, <4 x i1>, <4 x double>) -declare <2 x double> @llvm.masked.gather.v2f64(<2 x double*>, i32, <2 x i1>, <2 x double>) +declare <4 x float> @llvm.masked.gather.v4f32.v4p0f32(<4 x float*>, i32, <4 x i1>, <4 x float>) +declare <4 x double> @llvm.masked.gather.v4f64.v4p0f64(<4 x double*>, i32, <4 x i1>, <4 x double>) +declare <2 x double> @llvm.masked.gather.v2f64.v2p0f64(<2 x double*>, i32, <2 x i1>, <2 x double>) ; Gather smaller than existing instruction define <4 x float> @test15(float* %base, <4 x i32> %ind, <4 x i1> %mask) { @@ -831,7 +831,7 @@ define <4 x float> @test15(float* %base, <4 x i32> %ind, <4 x i1> %mask) { %sext_ind = sext <4 x i32> %ind to <4 x i64> %gep.random = getelementptr float, float* %base, <4 x i64> %sext_ind - %res = call <4 x float> @llvm.masked.gather.v4f32(<4 x float*> %gep.random, i32 4, <4 x i1> %mask, <4 x float> undef) + %res = call <4 x float> @llvm.masked.gather.v4f32.v4p0f32(<4 x float*> %gep.random, i32 4, <4 x i1> %mask, <4 x float> undef) ret <4 x float>%res } @@ -890,7 +890,7 @@ define <4 x double> @test16(double* %base, <4 x i32> %ind, <4 x i1> %mask, <4 x %sext_ind = sext <4 x i32> %ind to <4 x i64> %gep.random = getelementptr double, double* %base, <4 x i64> %sext_ind - %res = call <4 x double> @llvm.masked.gather.v4f64(<4 x double*> %gep.random, i32 4, <4 x i1> %mask, <4 x double> %src0) + %res = call <4 x double> @llvm.masked.gather.v4f64.v4p0f64(<4 x double*> %gep.random, i32 4, <4 x i1> %mask, <4 x double> %src0) ret <4 x double>%res } @@ -942,15 +942,15 @@ define <2 x double> @test17(double* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x %sext_ind = sext <2 x i32> %ind to <2 x i64> %gep.random = getelementptr double, double* %base, <2 x i64> %sext_ind - %res = call <2 x double> @llvm.masked.gather.v2f64(<2 x double*> %gep.random, i32 4, <2 x i1> %mask, <2 x double> %src0) + %res = call <2 x double> @llvm.masked.gather.v2f64.v2p0f64(<2 x double*> %gep.random, i32 4, <2 x i1> %mask, <2 x double> %src0) ret <2 x double>%res } -declare void @llvm.masked.scatter.v4i32(<4 x i32> , <4 x i32*> , i32 , <4 x i1> ) -declare void @llvm.masked.scatter.v4f64(<4 x double> , <4 x double*> , i32 , <4 x i1> ) -declare void @llvm.masked.scatter.v2i64(<2 x i64> , <2 x i64*> , i32 , <2 x i1> ) -declare void @llvm.masked.scatter.v2i32(<2 x i32> , <2 x i32*> , i32 , <2 x i1> ) -declare void @llvm.masked.scatter.v2f32(<2 x float> , <2 x float*> , i32 , <2 x i1> ) +declare void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> , <4 x i32*> , i32 , <4 x i1> ) +declare void @llvm.masked.scatter.v4f64.v4p0f64(<4 x double> , <4 x double*> , i32 , <4 x i1> ) +declare void @llvm.masked.scatter.v2i64.v2p0i64(<2 x i64> , <2 x i64*> , i32 , <2 x i1> ) +declare void @llvm.masked.scatter.v2i32.v2p0i32(<2 x i32> , <2 x i32*> , i32 , <2 x i1> ) +declare void @llvm.masked.scatter.v2f32.v2p0f32(<2 x float> , <2 x float*> , i32 , <2 x i1> ) define void @test18(<4 x i32>%a1, <4 x i32*> %ptr, <4 x i1>%mask) { ; @@ -995,7 +995,7 @@ define void @test18(<4 x i32>%a1, <4 x i32*> %ptr, <4 x i1>%mask) { ; SKX_32-NEXT: vptestmd %xmm2, %xmm2, %k1 ; SKX_32-NEXT: vpscatterdd %xmm0, (,%xmm1) {%k1} ; SKX_32-NEXT: retl - call void @llvm.masked.scatter.v4i32(<4 x i32> %a1, <4 x i32*> %ptr, i32 4, <4 x i1> %mask) + call void @llvm.masked.scatter.v4i32.v4p0i32(<4 x i32> %a1, <4 x i32*> %ptr, i32 4, <4 x i1> %mask) ret void } @@ -1049,7 +1049,7 @@ define void @test19(<4 x double>%a1, double* %ptr, <4 x i1>%mask, <4 x i64> %ind ; SKX_32-NEXT: vzeroupper ; SKX_32-NEXT: retl %gep = getelementptr double, double* %ptr, <4 x i64> %ind - call void @llvm.masked.scatter.v4f64(<4 x double> %a1, <4 x double*> %gep, i32 8, <4 x i1> %mask) + call void @llvm.masked.scatter.v4f64.v4p0f64(<4 x double> %a1, <4 x double*> %gep, i32 8, <4 x i1> %mask) ret void } @@ -1103,7 +1103,7 @@ define void @test20(<2 x float>%a1, <2 x float*> %ptr, <2 x i1> %mask) { ; SKX_32-NEXT: kshiftrb $6, %k0, %k1 ; SKX_32-NEXT: vscatterdps %xmm0, (,%xmm1) {%k1} ; SKX_32-NEXT: retl - call void @llvm.masked.scatter.v2f32(<2 x float> %a1, <2 x float*> %ptr, i32 4, <2 x i1> %mask) + call void @llvm.masked.scatter.v2f32.v2p0f32(<2 x float> %a1, <2 x float*> %ptr, i32 4, <2 x i1> %mask) ret void } @@ -1157,12 +1157,12 @@ define void @test21(<2 x i32>%a1, <2 x i32*> %ptr, <2 x i1>%mask) { ; SKX_32-NEXT: vpscatterqd %xmm0, (,%ymm1) {%k1} ; SKX_32-NEXT: vzeroupper ; SKX_32-NEXT: retl - call void @llvm.masked.scatter.v2i32(<2 x i32> %a1, <2 x i32*> %ptr, i32 4, <2 x i1> %mask) + call void @llvm.masked.scatter.v2i32.v2p0i32(<2 x i32> %a1, <2 x i32*> %ptr, i32 4, <2 x i1> %mask) ret void } ; The result type requires widening -declare <2 x float> @llvm.masked.gather.v2f32(<2 x float*>, i32, <2 x i1>, <2 x float>) +declare <2 x float> @llvm.masked.gather.v2f32.v2p0f32(<2 x float*>, i32, <2 x i1>, <2 x float>) define <2 x float> @test22(float* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x float> %src0) { ; @@ -1222,12 +1222,12 @@ define <2 x float> @test22(float* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x fl ; SKX_32-NEXT: retl %sext_ind = sext <2 x i32> %ind to <2 x i64> %gep.random = getelementptr float, float* %base, <2 x i64> %sext_ind - %res = call <2 x float> @llvm.masked.gather.v2f32(<2 x float*> %gep.random, i32 4, <2 x i1> %mask, <2 x float> %src0) + %res = call <2 x float> @llvm.masked.gather.v2f32.v2p0f32(<2 x float*> %gep.random, i32 4, <2 x i1> %mask, <2 x float> %src0) ret <2 x float>%res } -declare <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*>, i32, <2 x i1>, <2 x i32>) -declare <2 x i64> @llvm.masked.gather.v2i64(<2 x i64*>, i32, <2 x i1>, <2 x i64>) +declare <2 x i32> @llvm.masked.gather.v2i32.v2p0i32(<2 x i32*>, i32, <2 x i1>, <2 x i32>) +declare <2 x i64> @llvm.masked.gather.v2i64.v2p0i64(<2 x i64*>, i32, <2 x i1>, <2 x i64>) define <2 x i32> @test23(i32* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x i32> %src0) { ; @@ -1276,7 +1276,7 @@ define <2 x i32> @test23(i32* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x i32> % ; SKX_32-NEXT: retl %sext_ind = sext <2 x i32> %ind to <2 x i64> %gep.random = getelementptr i32, i32* %base, <2 x i64> %sext_ind - %res = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %gep.random, i32 4, <2 x i1> %mask, <2 x i32> %src0) + %res = call <2 x i32> @llvm.masked.gather.v2i32.v2p0i32(<2 x i32*> %gep.random, i32 4, <2 x i1> %mask, <2 x i32> %src0) ret <2 x i32>%res } @@ -1320,7 +1320,7 @@ define <2 x i32> @test24(i32* %base, <2 x i32> %ind) { ; SKX_32-NEXT: retl %sext_ind = sext <2 x i32> %ind to <2 x i64> %gep.random = getelementptr i32, i32* %base, <2 x i64> %sext_ind - %res = call <2 x i32> @llvm.masked.gather.v2i32(<2 x i32*> %gep.random, i32 4, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) + %res = call <2 x i32> @llvm.masked.gather.v2i32.v2p0i32(<2 x i32*> %gep.random, i32 4, <2 x i1> <i1 true, i1 true>, <2 x i32> undef) ret <2 x i32>%res } @@ -1371,7 +1371,7 @@ define <2 x i64> @test25(i64* %base, <2 x i32> %ind, <2 x i1> %mask, <2 x i64> % ; SKX_32-NEXT: retl %sext_ind = sext <2 x i32> %ind to <2 x i64> %gep.random = getelementptr i64, i64* %base, <2 x i64> %sext_ind - %res = call <2 x i64> @llvm.masked.gather.v2i64(<2 x i64*> %gep.random, i32 8, <2 x i1> %mask, <2 x i64> %src0) + %res = call <2 x i64> @llvm.masked.gather.v2i64.v2p0i64(<2 x i64*> %gep.random, i32 8, <2 x i1> %mask, <2 x i64> %src0) ret <2 x i64>%res } @@ -1418,7 +1418,7 @@ define <2 x i64> @test26(i64* %base, <2 x i32> %ind, <2 x i64> %src0) { ; SKX_32-NEXT: retl %sext_ind = sext <2 x i32> %ind to <2 x i64> %gep.random = getelementptr i64, i64* %base, <2 x i64> %sext_ind - %res = call <2 x i64> @llvm.masked.gather.v2i64(<2 x i64*> %gep.random, i32 8, <2 x i1> <i1 true, i1 true>, <2 x i64> %src0) + %res = call <2 x i64> @llvm.masked.gather.v2i64.v2p0i64(<2 x i64*> %gep.random, i32 8, <2 x i1> <i1 true, i1 true>, <2 x i64> %src0) ret <2 x i64>%res } @@ -1466,7 +1466,7 @@ define <2 x float> @test27(float* %base, <2 x i32> %ind) { ; SKX_32-NEXT: retl %sext_ind = sext <2 x i32> %ind to <2 x i64> %gep.random = getelementptr float, float* %base, <2 x i64> %sext_ind - %res = call <2 x float> @llvm.masked.gather.v2f32(<2 x float*> %gep.random, i32 4, <2 x i1> <i1 true, i1 true>, <2 x float> undef) + %res = call <2 x float> @llvm.masked.gather.v2f32.v2p0f32(<2 x float*> %gep.random, i32 4, <2 x i1> <i1 true, i1 true>, <2 x float> undef) ret <2 x float>%res } @@ -1515,7 +1515,7 @@ define void @test28(<2 x i32>%a1, <2 x i32*> %ptr) { ; SKX_32-NEXT: vpscatterqd %xmm0, (,%ymm1) {%k1} ; SKX_32-NEXT: vzeroupper ; SKX_32-NEXT: retl - call void @llvm.masked.scatter.v2i32(<2 x i32> %a1, <2 x i32*> %ptr, i32 4, <2 x i1> <i1 true, i1 true>) + call void @llvm.masked.scatter.v2i32.v2p0i32(<2 x i32> %a1, <2 x i32*> %ptr, i32 4, <2 x i1> <i1 true, i1 true>) ret void } @@ -1568,23 +1568,23 @@ define <16 x float> @test29(float* %base, <16 x i32> %ind) { %sext_ind = sext <16 x i32> %ind to <16 x i64> %gep.random = getelementptr float, <16 x float*> %broadcast.splat, <16 x i64> %sext_ind - %res = call <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 false, i1 false, i1 true, i1 true, i1 false, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <16 x float> undef) + %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %gep.random, i32 4, <16 x i1> <i1 false, i1 false, i1 true, i1 true, i1 false, i1 true, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false, i1 false>, <16 x float> undef) ret <16 x float>%res } ; Check non-power-of-2 case. It should be scalarized. -declare <3 x i32> @llvm.masked.gather.v3i32(<3 x i32*>, i32, <3 x i1>, <3 x i32>) +declare <3 x i32> @llvm.masked.gather.v3i32.v3p0i32(<3 x i32*>, i32, <3 x i1>, <3 x i32>) define <3 x i32> @test30(<3 x i32*> %base, <3 x i32> %ind, <3 x i1> %mask, <3 x i32> %src0) { ; ALL-LABEL: test30: ; ALL-NOT: gather %sext_ind = sext <3 x i32> %ind to <3 x i64> %gep.random = getelementptr i32, <3 x i32*> %base, <3 x i64> %sext_ind - %res = call <3 x i32> @llvm.masked.gather.v3i32(<3 x i32*> %gep.random, i32 4, <3 x i1> %mask, <3 x i32> %src0) + %res = call <3 x i32> @llvm.masked.gather.v3i32.v3p0i32(<3 x i32*> %gep.random, i32 4, <3 x i1> %mask, <3 x i32> %src0) ret <3 x i32>%res } -declare <16 x float*> @llvm.masked.gather.v16p0f32(<16 x float**>, i32, <16 x i1>, <16 x float*>) +declare <16 x float*> @llvm.masked.gather.v16p0f32.v16p0p0f32(<16 x float**>, i32, <16 x i1>, <16 x float*>) ; KNL-LABEL: test31 ; KNL: vpgatherqq @@ -1626,7 +1626,7 @@ define <16 x float*> @test31(<16 x float**> %ptrs) { ; SKX_32-NEXT: vmovdqa64 %zmm1, %zmm0 ; SKX_32-NEXT: retl - %res = call <16 x float*> @llvm.masked.gather.v16p0f32(<16 x float**> %ptrs, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float*> undef) + %res = call <16 x float*> @llvm.masked.gather.v16p0f32.v16p0p0f32(<16 x float**> %ptrs, i32 4, <16 x i1> <i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true, i1 true>, <16 x float*> undef) ret <16 x float*>%res } @@ -1672,7 +1672,7 @@ define <16 x i32> @test_gather_16i32(<16 x i32*> %ptrs, <16 x i1> %mask, <16 x i ; SKX_32-NEXT: vpgatherdd (,%zmm0), %zmm2 {%k1} ; SKX_32-NEXT: vmovdqa64 %zmm2, %zmm0 ; SKX_32-NEXT: retl - %res = call <16 x i32> @llvm.masked.gather.v16i32(<16 x i32*> %ptrs, i32 4, <16 x i1> %mask, <16 x i32> %src0) + %res = call <16 x i32> @llvm.masked.gather.v16i32.v16p0i32(<16 x i32*> %ptrs, i32 4, <16 x i1> %mask, <16 x i32> %src0) ret <16 x i32> %res } define <16 x i64> @test_gather_16i64(<16 x i64*> %ptrs, <16 x i1> %mask, <16 x i64> %src0) { @@ -1749,10 +1749,10 @@ define <16 x i64> @test_gather_16i64(<16 x i64*> %ptrs, <16 x i1> %mask, <16 x i ; SKX_32-NEXT: movl %ebp, %esp ; SKX_32-NEXT: popl %ebp ; SKX_32-NEXT: retl - %res = call <16 x i64> @llvm.masked.gather.v16i64(<16 x i64*> %ptrs, i32 4, <16 x i1> %mask, <16 x i64> %src0) + %res = call <16 x i64> @llvm.masked.gather.v16i64.v16p0i64(<16 x i64*> %ptrs, i32 4, <16 x i1> %mask, <16 x i64> %src0) ret <16 x i64> %res } -declare <16 x i64> @llvm.masked.gather.v16i64(<16 x i64*> %ptrs, i32, <16 x i1> %mask, <16 x i64> %src0) +declare <16 x i64> @llvm.masked.gather.v16i64.v16p0i64(<16 x i64*> %ptrs, i32, <16 x i1> %mask, <16 x i64> %src0) define <16 x float> @test_gather_16f32(<16 x float*> %ptrs, <16 x i1> %mask, <16 x float> %src0) { ; KNL_64-LABEL: test_gather_16f32: ; KNL_64: # BB#0: @@ -1795,7 +1795,7 @@ define <16 x float> @test_gather_16f32(<16 x float*> %ptrs, <16 x i1> %mask, <16 ; SKX_32-NEXT: vgatherdps (,%zmm0), %zmm2 {%k1} ; SKX_32-NEXT: vmovaps %zmm2, %zmm0 ; SKX_32-NEXT: retl - %res = call <16 x float> @llvm.masked.gather.v16f32(<16 x float*> %ptrs, i32 4, <16 x i1> %mask, <16 x float> %src0) + %res = call <16 x float> @llvm.masked.gather.v16f32.v16p0f32(<16 x float*> %ptrs, i32 4, <16 x i1> %mask, <16 x float> %src0) ret <16 x float> %res } define <16 x double> @test_gather_16f64(<16 x double*> %ptrs, <16 x i1> %mask, <16 x double> %src0) { @@ -1872,10 +1872,10 @@ define <16 x double> @test_gather_16f64(<16 x double*> %ptrs, <16 x i1> %mask, < ; SKX_32-NEXT: movl %ebp, %esp ; SKX_32-NEXT: popl %ebp ; SKX_32-NEXT: retl - %res = call <16 x double> @llvm.masked.gather.v16f64(<16 x double*> %ptrs, i32 4, <16 x i1> %mask, <16 x double> %src0) + %res = call <16 x double> @llvm.masked.gather.v16f64.v16p0f64(<16 x double*> %ptrs, i32 4, <16 x i1> %mask, <16 x double> %src0) ret <16 x double> %res } -declare <16 x double> @llvm.masked.gather.v16f64(<16 x double*> %ptrs, i32, <16 x i1> %mask, <16 x double> %src0) +declare <16 x double> @llvm.masked.gather.v16f64.v16p0f64(<16 x double*> %ptrs, i32, <16 x i1> %mask, <16 x double> %src0) define void @test_scatter_16i32(<16 x i32*> %ptrs, <16 x i1> %mask, <16 x i32> %src0) { ; KNL_64-LABEL: test_scatter_16i32: ; KNL_64: # BB#0: @@ -1918,7 +1918,7 @@ define void @test_scatter_16i32(<16 x i32*> %ptrs, <16 x i1> %mask, <16 x i32> % ; SKX_32-NEXT: vpscatterdd %zmm2, (,%zmm0) {%k1} ; SKX_32-NEXT: vzeroupper ; SKX_32-NEXT: retl - call void @llvm.masked.scatter.v16i32(<16 x i32> %src0, <16 x i32*> %ptrs, i32 4, <16 x i1> %mask) + call void @llvm.masked.scatter.v16i32.v16p0i32(<16 x i32> %src0, <16 x i32*> %ptrs, i32 4, <16 x i1> %mask) ret void } define void @test_scatter_16i64(<16 x i64*> %ptrs, <16 x i1> %mask, <16 x i64> %src0) { @@ -1993,10 +1993,10 @@ define void @test_scatter_16i64(<16 x i64*> %ptrs, <16 x i1> %mask, <16 x i64> % ; SKX_32-NEXT: popl %ebp ; SKX_32-NEXT: vzeroupper ; SKX_32-NEXT: retl - call void @llvm.masked.scatter.v16i64(<16 x i64> %src0, <16 x i64*> %ptrs, i32 4, <16 x i1> %mask) + call void @llvm.masked.scatter.v16i64.v16p0i64(<16 x i64> %src0, <16 x i64*> %ptrs, i32 4, <16 x i1> %mask) ret void } -declare void @llvm.masked.scatter.v16i64(<16 x i64> %src0, <16 x i64*> %ptrs, i32, <16 x i1> %mask) +declare void @llvm.masked.scatter.v16i64.v16p0i64(<16 x i64> %src0, <16 x i64*> %ptrs, i32, <16 x i1> %mask) define void @test_scatter_16f32(<16 x float*> %ptrs, <16 x i1> %mask, <16 x float> %src0) { ; KNL_64-LABEL: test_scatter_16f32: ; KNL_64: # BB#0: @@ -2039,10 +2039,10 @@ define void @test_scatter_16f32(<16 x float*> %ptrs, <16 x i1> %mask, <16 x floa ; SKX_32-NEXT: vscatterdps %zmm2, (,%zmm0) {%k1} ; SKX_32-NEXT: vzeroupper ; SKX_32-NEXT: retl - call void @llvm.masked.scatter.v16f32(<16 x float> %src0, <16 x float*> %ptrs, i32 4, <16 x i1> %mask) + call void @llvm.masked.scatter.v16f32.v16p0f32(<16 x float> %src0, <16 x float*> %ptrs, i32 4, <16 x i1> %mask) ret void } -declare void @llvm.masked.scatter.v16f32(<16 x float> %src0, <16 x float*> %ptrs, i32, <16 x i1> %mask) +declare void @llvm.masked.scatter.v16f32.v16p0f32(<16 x float> %src0, <16 x float*> %ptrs, i32, <16 x i1> %mask) define void @test_scatter_16f64(<16 x double*> %ptrs, <16 x i1> %mask, <16 x double> %src0) { ; KNL_64-LABEL: test_scatter_16f64: ; KNL_64: # BB#0: @@ -2115,10 +2115,10 @@ define void @test_scatter_16f64(<16 x double*> %ptrs, <16 x i1> %mask, <16 x dou ; SKX_32-NEXT: popl %ebp ; SKX_32-NEXT: vzeroupper ; SKX_32-NEXT: retl - call void @llvm.masked.scatter.v16f64(<16 x double> %src0, <16 x double*> %ptrs, i32 4, <16 x i1> %mask) + call void @llvm.masked.scatter.v16f64.v16p0f64(<16 x double> %src0, <16 x double*> %ptrs, i32 4, <16 x i1> %mask) ret void } -declare void @llvm.masked.scatter.v16f64(<16 x double> %src0, <16 x double*> %ptrs, i32, <16 x i1> %mask) +declare void @llvm.masked.scatter.v16f64.v16p0f64(<16 x double> %src0, <16 x double*> %ptrs, i32, <16 x i1> %mask) define <4 x i64> @test_pr28312(<4 x i64*> %p1, <4 x i1> %k, <4 x i1> %k2,<4 x i64> %d) { ; KNL_64-LABEL: test_pr28312: @@ -2193,11 +2193,11 @@ define <4 x i64> @test_pr28312(<4 x i64*> %p1, <4 x i1> %k, <4 x i1> %k2,<4 x i6 ; SKX_32-NEXT: movl %ebp, %esp ; SKX_32-NEXT: popl %ebp ; SKX_32-NEXT: retl - %g1 = call <4 x i64> @llvm.masked.gather.v4i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef) - %g2 = call <4 x i64> @llvm.masked.gather.v4i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef) - %g3 = call <4 x i64> @llvm.masked.gather.v4i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef) + %g1 = call <4 x i64> @llvm.masked.gather.v4i64.v4p0i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef) + %g2 = call <4 x i64> @llvm.masked.gather.v4i64.v4p0i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef) + %g3 = call <4 x i64> @llvm.masked.gather.v4i64.v4p0i64(<4 x i64*> %p1, i32 8, <4 x i1> %k, <4 x i64> undef) %a = add <4 x i64> %g1, %g2 %b = add <4 x i64> %a, %g3 ret <4 x i64> %b } -declare <4 x i64> @llvm.masked.gather.v4i64(<4 x i64*>, i32, <4 x i1>, <4 x i64>) +declare <4 x i64> @llvm.masked.gather.v4i64.v4p0i64(<4 x i64*>, i32, <4 x i1>, <4 x i64>) diff --git a/test/CodeGen/X86/stack-folding-lwp.ll b/test/CodeGen/X86/stack-folding-lwp.ll new file mode 100644 index 0000000000000..edf2798ff8466 --- /dev/null +++ b/test/CodeGen/X86/stack-folding-lwp.ll @@ -0,0 +1,49 @@ +; RUN: llc -O3 -disable-peephole -mtriple=x86_64-unknown-unknown -mattr=+lwp < %s | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-unknown" + +; Stack reload folding tests. +; +; By including a nop call with sideeffects we can force a partial register spill of the +; relevant registers and check that the reload is correctly folded into the instruction. + +define i8 @stack_fold_lwpins_u32(i32 %a0, i32 %a1) { +; CHECK-LABEL: stack_fold_lwpins_u32 +; CHECK: # BB#0: +; CHECK: lwpins $2814, {{-?[0-9]*}}(%rsp), %eax {{.*#+}} 4-byte Folded Reload + %1 = tail call i64 asm sideeffect "nop", "=x,~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() + %2 = tail call i8 @llvm.x86.lwpins32(i32 %a0, i32 %a1, i32 2814) + ret i8 %2 +} +declare i8 @llvm.x86.lwpins32(i32, i32, i32) + +define i8 @stack_fold_lwpins_u64(i64 %a0, i32 %a1) { +; CHECK-LABEL: stack_fold_lwpins_u64 +; CHECK: # BB#0: +; CHECK: lwpins $2814, {{-?[0-9]*}}(%rsp), %rax {{.*#+}} 4-byte Folded Reload + %1 = tail call i64 asm sideeffect "nop", "=x,~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() + %2 = tail call i8 @llvm.x86.lwpins64(i64 %a0, i32 %a1, i32 2814) + ret i8 %2 +} +declare i8 @llvm.x86.lwpins64(i64, i32, i32) + +define void @stack_fold_lwpval_u32(i32 %a0, i32 %a1) { +; CHECK-LABEL: stack_fold_lwpval_u32 +; CHECK: # BB#0: +; CHECK: lwpval $2814, {{-?[0-9]*}}(%rsp), %eax {{.*#+}} 4-byte Folded Reload + %1 = tail call i64 asm sideeffect "nop", "=x,~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() + tail call void @llvm.x86.lwpval32(i32 %a0, i32 %a1, i32 2814) + ret void +} +declare void @llvm.x86.lwpval32(i32, i32, i32) + +define void @stack_fold_lwpval_u64(i64 %a0, i32 %a1) { +; CHECK-LABEL: stack_fold_lwpval_u64 +; CHECK: # BB#0: +; CHECK: lwpval $2814, {{-?[0-9]*}}(%rsp), %rax {{.*#+}} 4-byte Folded Reload + %1 = tail call i64 asm sideeffect "nop", "=x,~{rax},~{rbx},~{rcx},~{rdx},~{rsi},~{rdi},~{rbp},~{r8},~{r9},~{r10},~{r11},~{r12},~{r13},~{r14},~{r15}"() + tail call void @llvm.x86.lwpval64(i64 %a0, i32 %a1, i32 2814) + ret void +} +declare void @llvm.x86.lwpval64(i64, i32, i32) diff --git a/test/CodeGen/X86/version_directive.ll b/test/CodeGen/X86/version_directive.ll index 8e4e6dc70e61b..ac5eda71dbc68 100644 --- a/test/CodeGen/X86/version_directive.ll +++ b/test/CodeGen/X86/version_directive.ll @@ -1,4 +1,5 @@ ; RUN: llc -mtriple x86_64-apple-darwin15.0.0 -o - /dev/null | FileCheck %s ; RUN: llc -mtriple x86_64-apple-macosx10.11.0 -o - /dev/null | FileCheck %s +; RUN: llc -mtriple x86_64-apple-macos10.11.0 -o - /dev/null | FileCheck %s ; CHECK: .macosx_version_min 10, 11 diff --git a/test/CodeGen/X86/x86-32-intrcc.ll b/test/CodeGen/X86/x86-32-intrcc.ll index 9794f2cb3e468..ac0e7e11e0e8b 100644 --- a/test/CodeGen/X86/x86-32-intrcc.ll +++ b/test/CodeGen/X86/x86-32-intrcc.ll @@ -57,23 +57,23 @@ define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i32 %eco define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i32 %ecode) { call void asm sideeffect "", "~{eax},~{ebx},~{ebp}"() ; CHECK-LABEL: test_isr_clobbers - ; CHECK-SSE-NEXT: pushl %ebp - ; CHECK-SSE-NEXT: pushl %ebx - ; CHECK-SSE-NEXT; pushl %eax - ; CHECK-SSE-NEXT: popl %eax - ; CHECK-SSE-NEXT: popl %ebx - ; CHECK-SSE-NEXT: popl %ebp - ; CHECK-SSE-NEXT: addl $4, %esp - ; CHECK-SSE-NEXT: iretl + ; CHECK: pushl %ebp + ; CHECK: pushl %ebx + ; CHECK: pushl %eax + ; CHECK: popl %eax + ; CHECK: popl %ebx + ; CHECK: popl %ebp + ; CHECK: addl $4, %esp + ; CHECK: iretl ; CHECK0-LABEL: test_isr_clobbers - ; CHECK0-SSE-NEXT: pushl %ebp - ; CHECK0-SSE-NEXT: pushl %ebx - ; CHECK0-SSE-NEXT; pushl %eax - ; CHECK0-SSE-NEXT: popl %eax - ; CHECK0-SSE-NEXT: popl %ebx - ; CHECK0-SSE-NEXT: popl %ebp - ; CHECK0-SSE-NEXT: addl $4, %esp - ; CHECK0-SSE-NEXT: iretl + ; CHECK0: pushl %ebp + ; CHECK0: pushl %ebx + ; CHECK0: pushl %eax + ; CHECK0: popl %eax + ; CHECK0: popl %ebx + ; CHECK0: popl %ebp + ; CHECK0: addl $4, %esp + ; CHECK0: iretl ret void } diff --git a/test/CodeGen/X86/x86-64-intrcc.ll b/test/CodeGen/X86/x86-64-intrcc.ll index c8bc9e716ce54..75ca1af79b31e 100644 --- a/test/CodeGen/X86/x86-64-intrcc.ll +++ b/test/CodeGen/X86/x86-64-intrcc.ll @@ -59,32 +59,33 @@ define x86_intrcc void @test_isr_ecode(%struct.interrupt_frame* %frame, i64 %eco define x86_intrcc void @test_isr_clobbers(%struct.interrupt_frame* %frame, i64 %ecode) { call void asm sideeffect "", "~{rax},~{rbx},~{rbp},~{r11},~{xmm0}"() ; CHECK-LABEL: test_isr_clobbers - ; CHECK-SSE-NEXT: pushq %rax - ; CHECK-SSE-NEXT: pushq %rax - ; CHECK-SSE-NEXT; pushq %r11 - ; CHECK-SSE-NEXT: pushq %rbp - ; CHECK-SSE-NEXT: pushq %rbx - ; CHECK-SSE-NEXT: movaps %xmm0 - ; CHECK-SSE-NEXT: movaps %xmm0 - ; CHECK-SSE-NEXT: popq %rbx - ; CHECK-SSE-NEXT: popq %rbp - ; CHECK-SSE-NEXT: popq %r11 - ; CHECK-SSE-NEXT: popq %rax - ; CHECK-SSE-NEXT: addq $8, %rsp - ; CHECK-SSE-NEXT: iretq + + ; CHECK: pushq %rax + ; CHECK: pushq %rbp + ; CHECK: pushq %r11 + ; CHECK: pushq %rbx + ; CHECK: movaps %xmm0 + ; CHECK: movaps {{.*}}, %xmm0 + ; CHECK: popq %rbx + ; CHECK: popq %r11 + ; CHECK: popq %rbp + ; CHECK: popq %rax + ; CHECK: addq $16, %rsp + ; CHECK: iretq ; CHECK0-LABEL: test_isr_clobbers - ; CHECK0-SSE-NEXT: pushq %rax - ; CHECK0-SSE-NEXT; pushq %r11 - ; CHECK0-SSE-NEXT: pushq %rbp - ; CHECK0-SSE-NEXT: pushq %rbx - ; CHECK0-SSE-NEXT: movaps %xmm0 - ; CHECK0-SSE-NEXT: movaps %xmm0 - ; CHECK0-SSE-NEXT: popq %rbx - ; CHECK0-SSE-NEXT: popq %rbp - ; CHECK0-SSE-NEXT: popq %r11 - ; CHECK0-SSE-NEXT: popq %rax - ; CHECK0-SSE-NEXT: addq $16, %rsp - ; CHECK0-SSE-NEXT: iretq + + ; CHECK0: pushq %rax + ; CHECK0: pushq %rbp + ; CHECK0: pushq %r11 + ; CHECK0: pushq %rbx + ; CHECK0: movaps %xmm0 + ; CHECK0: movaps {{.*}}, %xmm0 + ; CHECK0: popq %rbx + ; CHECK0: popq %r11 + ; CHECK0: popq %rbp + ; CHECK0: popq %rax + ; CHECK0: addq $16, %rsp + ; CHECK0: iretq ret void } diff --git a/test/CodeGen/X86/x86-no_caller_saved_registers-preserve.ll b/test/CodeGen/X86/x86-no_caller_saved_registers-preserve.ll new file mode 100644 index 0000000000000..7e370c25e31bb --- /dev/null +++ b/test/CodeGen/X86/x86-no_caller_saved_registers-preserve.ll @@ -0,0 +1,54 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py for function "bar" +; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s + +;; In functions with 'no_caller_saved_registers' attribute, all registers should
+;; be preserved except for registers used for passing/returning arguments. +;; In the following function registers %RDI, %RSI and %XMM0 are used to store +;; arguments %a0, %a1 and %b0 accordingally. The value is returned in %RAX. +;; The above registers should not be preserved, however other registers +;; (that are modified by the function) should be preserved (%RDX and %XMM1). +define x86_64_sysvcc i32 @bar(i32 %a0, i32 %a1, float %b0) #0 { +; CHECK-LABEL: bar: +; CHECK: # BB#0: +; CHECK-NEXT: pushq %rdx +; CHECK-NEXT: .Lcfi0: +; CHECK-NEXT: .cfi_def_cfa_offset 16 +; CHECK-NEXT: movaps %xmm1, -{{[0-9]+}}(%rsp) # 16-byte Spill +; CHECK-NEXT: .Lcfi1: +; CHECK-NEXT: .cfi_offset %rdx, -16 +; CHECK-NEXT: .Lcfi2: +; CHECK-NEXT: .cfi_offset %xmm1, -32 +; CHECK-NEXT: #APP +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: movl $4, %eax +; CHECK-NEXT: movaps -{{[0-9]+}}(%rsp), %xmm1 # 16-byte Reload +; CHECK-NEXT: popq %rdx +; CHECK-NEXT: retq + call void asm sideeffect "", "~{rax},~{rdx},~{xmm1},~{rdi},~{rsi},~{xmm0}"() + ret i32 4 +} + +;; Because "bar" has 'no_caller_saved_registers' attribute, function "foo"
+;; doesn't need to preserve registers except for the arguments passed
+;; to "bar" (%ESI, %EDI and %XMM0). +define x86_64_sysvcc float @foo(i32 %a0, i32 %a1, float %b0) { +; CHECK-LABEL: foo
+; CHECK: movaps %xmm0, %xmm1
+; CHECK-NEXT: movl %esi, %ecx
+; CHECK-NEXT: movl %edi, %edx
+; CHECK-NEXT: callq bar
+; CHECK-NEXT: addl %edx, %eax
+; CHECK-NEXT: addl %ecx, %eax
+; CHECK-NEXT: xorps %xmm0, %xmm0
+; CHECK-NEXT: cvtsi2ssl %eax, %xmm0
+; CHECK-NEXT: addss %xmm0, %xmm1
+; CHECK: retq + %call = call i32 @bar(i32 %a0, i32 %a1, float %b0) #0 + %c0 = add i32 %a0, %call + %c1 = add i32 %c0, %a1 + %c2 = sitofp i32 %c1 to float + %c3 = fadd float %c2, %b0 + ret float %c3 +} + +attributes #0 = { "no_caller_saved_registers" } diff --git a/test/CodeGen/X86/x86-no_caller_saved_registers.ll b/test/CodeGen/X86/x86-no_caller_saved_registers.ll new file mode 100644 index 0000000000000..9c62e3ee6ba75 --- /dev/null +++ b/test/CodeGen/X86/x86-no_caller_saved_registers.ll @@ -0,0 +1,31 @@ +; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s
+; RUN: llc -mtriple=x86_64-unknown-unknown -O0 < %s | FileCheck %s
+; RUN: llc -mtriple=i686-unknown-unknown -mattr=+sse2 < %s | FileCheck %s
+; RUN: llc -mtriple=i686-unknown-unknown -mattr=+sse2 -O0 < %s | FileCheck %s
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; In functions with 'no_caller_saved_registers' attribute, all registers should
+;; be preserved except for registers used for passing/returning arguments.
+;; The test checks that function "bar" preserves xmm0 register.
+;; It also checks that caller function "foo" does not store registers for callee
+;; "bar". For example, there is no store/load/access to xmm registers.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+define i32 @bar(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %a4, i32 %a5, i32 %a6, i32 %a7, i32 %a8) #0 {
+; CHECK-LABEL: bar
+; CHECK: mov{{.*}} %xmm0
+; CHECK: mov{{.*}} {{.*}}, %xmm0
+; CHECK: ret
+ call void asm sideeffect "", "~{xmm0}"()
+ ret i32 1
+}
+
+define x86_intrcc void @foo(i8* nocapture readnone %c) {
+; CHECK-LABEL: foo
+; CHECK-NOT: xmm
+entry:
+ tail call i32 @bar(i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8) #0
+ ret void
+}
+
+attributes #0 = { "no_caller_saved_registers" }
|
