aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGen/AMDGPU
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/AMDGPU')
-rw-r--r--test/CodeGen/AMDGPU/amdgpu-codegenprepare.ll246
-rw-r--r--test/CodeGen/AMDGPU/amdgpu.private-memory.ll35
-rw-r--r--test/CodeGen/AMDGPU/basic-branch.ll1
-rw-r--r--test/CodeGen/AMDGPU/fdiv.ll251
-rw-r--r--test/CodeGen/AMDGPU/fp_to_sint.f64.ll23
-rw-r--r--test/CodeGen/AMDGPU/fp_to_sint.ll28
-rw-r--r--test/CodeGen/AMDGPU/fp_to_uint.f64.ll23
-rw-r--r--test/CodeGen/AMDGPU/fp_to_uint.ll30
-rw-r--r--test/CodeGen/AMDGPU/invalid-opencl-version-metadata1.ll8
-rw-r--r--test/CodeGen/AMDGPU/invalid-opencl-version-metadata2.ll9
-rw-r--r--test/CodeGen/AMDGPU/invalid-opencl-version-metadata3.ll9
-rw-r--r--test/CodeGen/AMDGPU/llvm.amdgcn.fdiv.fast.ll18
-rw-r--r--test/CodeGen/AMDGPU/llvm.amdgcn.groupstaticsize.ll (renamed from test/CodeGen/AMDGPU/llvm.amdgcn.groupstaticgroup.ll)24
-rw-r--r--test/CodeGen/AMDGPU/rcp-pattern.ll91
-rw-r--r--test/CodeGen/AMDGPU/reciprocal.ll13
-rw-r--r--test/CodeGen/AMDGPU/skip-if-dead.ll2
-rw-r--r--test/CodeGen/AMDGPU/vector-alloca.ll119
-rw-r--r--test/CodeGen/AMDGPU/wqm.ll154
18 files changed, 830 insertions, 254 deletions
diff --git a/test/CodeGen/AMDGPU/amdgpu-codegenprepare.ll b/test/CodeGen/AMDGPU/amdgpu-codegenprepare.ll
index a12132f425d9..d78c75165be2 100644
--- a/test/CodeGen/AMDGPU/amdgpu-codegenprepare.ll
+++ b/test/CodeGen/AMDGPU/amdgpu-codegenprepare.ll
@@ -1,8 +1,246 @@
-; RUN: opt -S -mtriple=amdgcn-- -amdgpu-codegenprepare < %s | FileCheck %s
-; RUN: opt -S -amdgpu-codegenprepare < %s
+; RUN: opt -S -mtriple=amdgcn-- -amdgpu-codegenprepare %s | FileCheck %s
+; RUN: opt -S -amdgpu-codegenprepare %s | FileCheck -check-prefix=NOOP %s
; Make sure this doesn't crash with no triple
-; CHECK-LABEL: @foo(
-define void @foo() {
+; NOOP-LABEL: @noop_fdiv_fpmath(
+; NOOP: %md.25ulp = fdiv float %a, %b, !fpmath !0
+define void @noop_fdiv_fpmath(float addrspace(1)* %out, float %a, float %b) #3 {
+ %md.25ulp = fdiv float %a, %b, !fpmath !0
+ store volatile float %md.25ulp, float addrspace(1)* %out
ret void
}
+
+; CHECK-LABEL: @fdiv_fpmath(
+; CHECK: %no.md = fdiv float %a, %b{{$}}
+; CHECK: %md.half.ulp = fdiv float %a, %b, !fpmath !1
+; CHECK: %md.1ulp = fdiv float %a, %b, !fpmath !2
+; CHECK: %md.25ulp = call float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
+; CHECK: %md.3ulp = call float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !3
+; CHECK: %fast.md.25ulp = call fast float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
+; CHECK: arcp.md.25ulp = call arcp float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
+define void @fdiv_fpmath(float addrspace(1)* %out, float %a, float %b) #1 {
+ %no.md = fdiv float %a, %b
+ store volatile float %no.md, float addrspace(1)* %out
+
+ %md.half.ulp = fdiv float %a, %b, !fpmath !1
+ store volatile float %md.half.ulp, float addrspace(1)* %out
+
+ %md.1ulp = fdiv float %a, %b, !fpmath !2
+ store volatile float %md.1ulp, float addrspace(1)* %out
+
+ %md.25ulp = fdiv float %a, %b, !fpmath !0
+ store volatile float %md.25ulp, float addrspace(1)* %out
+
+ %md.3ulp = fdiv float %a, %b, !fpmath !3
+ store volatile float %md.3ulp, float addrspace(1)* %out
+
+ %fast.md.25ulp = fdiv fast float %a, %b, !fpmath !0
+ store volatile float %fast.md.25ulp, float addrspace(1)* %out
+
+ %arcp.md.25ulp = fdiv arcp float %a, %b, !fpmath !0
+ store volatile float %arcp.md.25ulp, float addrspace(1)* %out
+
+ ret void
+}
+
+; CHECK-LABEL: @rcp_fdiv_fpmath(
+; CHECK: %no.md = fdiv float 1.000000e+00, %x{{$}}
+; CHECK: %md.25ulp = fdiv float 1.000000e+00, %x, !fpmath !0
+; CHECK: %md.half.ulp = fdiv float 1.000000e+00, %x, !fpmath !1
+; CHECK: %arcp.no.md = fdiv arcp float 1.000000e+00, %x{{$}}
+; CHECK: %arcp.25ulp = fdiv arcp float 1.000000e+00, %x, !fpmath !0
+; CHECK: %fast.no.md = fdiv fast float 1.000000e+00, %x{{$}}
+; CHECK: %fast.25ulp = fdiv fast float 1.000000e+00, %x, !fpmath !0
+define void @rcp_fdiv_fpmath(float addrspace(1)* %out, float %x) #1 {
+ %no.md = fdiv float 1.0, %x
+ store volatile float %no.md, float addrspace(1)* %out
+
+ %md.25ulp = fdiv float 1.0, %x, !fpmath !0
+ store volatile float %md.25ulp, float addrspace(1)* %out
+
+ %md.half.ulp = fdiv float 1.0, %x, !fpmath !1
+ store volatile float %md.half.ulp, float addrspace(1)* %out
+
+ %arcp.no.md = fdiv arcp float 1.0, %x
+ store volatile float %arcp.no.md, float addrspace(1)* %out
+
+ %arcp.25ulp = fdiv arcp float 1.0, %x, !fpmath !0
+ store volatile float %arcp.25ulp, float addrspace(1)* %out
+
+ %fast.no.md = fdiv fast float 1.0, %x
+ store volatile float %fast.no.md, float addrspace(1)* %out
+
+ %fast.25ulp = fdiv fast float 1.0, %x, !fpmath !0
+ store volatile float %fast.25ulp, float addrspace(1)* %out
+
+ ret void
+}
+
+; CHECK-LABEL: @fdiv_fpmath_vector(
+; CHECK: %no.md = fdiv <2 x float> %a, %b{{$}}
+; CHECK: %md.half.ulp = fdiv <2 x float> %a, %b, !fpmath !1
+; CHECK: %md.1ulp = fdiv <2 x float> %a, %b, !fpmath !2
+
+; CHECK: %[[A0:[0-9]+]] = extractelement <2 x float> %a, i64 0
+; CHECK: %[[B0:[0-9]+]] = extractelement <2 x float> %b, i64 0
+; CHECK: %[[FDIV0:[0-9]+]] = call float @llvm.amdgcn.fdiv.fast(float %[[A0]], float %[[B0]]), !fpmath !0
+; CHECK: %[[INS0:[0-9]+]] = insertelement <2 x float> undef, float %[[FDIV0]], i64 0
+; CHECK: %[[A1:[0-9]+]] = extractelement <2 x float> %a, i64 1
+; CHECK: %[[B1:[0-9]+]] = extractelement <2 x float> %b, i64 1
+; CHECK: %[[FDIV1:[0-9]+]] = call float @llvm.amdgcn.fdiv.fast(float %[[A1]], float %[[B1]]), !fpmath !0
+; CHECK: %md.25ulp = insertelement <2 x float> %[[INS0]], float %[[FDIV1]], i64 1
+define void @fdiv_fpmath_vector(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #1 {
+ %no.md = fdiv <2 x float> %a, %b
+ store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out
+
+ %md.half.ulp = fdiv <2 x float> %a, %b, !fpmath !1
+ store volatile <2 x float> %md.half.ulp, <2 x float> addrspace(1)* %out
+
+ %md.1ulp = fdiv <2 x float> %a, %b, !fpmath !2
+ store volatile <2 x float> %md.1ulp, <2 x float> addrspace(1)* %out
+
+ %md.25ulp = fdiv <2 x float> %a, %b, !fpmath !0
+ store volatile <2 x float> %md.25ulp, <2 x float> addrspace(1)* %out
+
+ ret void
+}
+
+; CHECK-LABEL: @rcp_fdiv_fpmath_vector(
+; CHECK: %no.md = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}}
+; CHECK: %md.half.ulp = fdiv <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x, !fpmath !1
+; CHECK: %arcp.no.md = fdiv arcp <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}}
+; CHECK: %fast.no.md = fdiv fast <2 x float> <float 1.000000e+00, float 1.000000e+00>, %x{{$}}
+
+; CHECK: extractelement <2 x float> %x
+; CHECK: fdiv arcp float 1.000000e+00, %{{[0-9]+}}, !fpmath !0
+; CHECK: extractelement <2 x float> %x
+; CHECK: fdiv arcp float 1.000000e+00, %{{[0-9]+}}, !fpmath !0
+; CHECK: store volatile <2 x float> %arcp.25ulp
+
+; CHECK: fdiv fast float 1.000000e+00, %{{[0-9]+}}, !fpmath !0
+; CHECK: fdiv fast float 1.000000e+00, %{{[0-9]+}}, !fpmath !0
+; CHECK: store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out
+define void @rcp_fdiv_fpmath_vector(<2 x float> addrspace(1)* %out, <2 x float> %x) #1 {
+ %no.md = fdiv <2 x float> <float 1.0, float 1.0>, %x
+ store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out
+
+ %md.half.ulp = fdiv <2 x float> <float 1.0, float 1.0>, %x, !fpmath !1
+ store volatile <2 x float> %md.half.ulp, <2 x float> addrspace(1)* %out
+
+ %arcp.no.md = fdiv arcp <2 x float> <float 1.0, float 1.0>, %x
+ store volatile <2 x float> %arcp.no.md, <2 x float> addrspace(1)* %out
+
+ %fast.no.md = fdiv fast <2 x float> <float 1.0, float 1.0>, %x
+ store volatile <2 x float> %fast.no.md, <2 x float> addrspace(1)* %out
+
+ %arcp.25ulp = fdiv arcp <2 x float> <float 1.0, float 1.0>, %x, !fpmath !0
+ store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out
+
+ %fast.25ulp = fdiv fast <2 x float> <float 1.0, float 1.0>, %x, !fpmath !0
+ store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out
+
+ ret void
+}
+
+; CHECK-LABEL: @rcp_fdiv_fpmath_vector_nonsplat(
+; CHECK: %no.md = fdiv <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x
+; CHECK: %arcp.no.md = fdiv arcp <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x
+; CHECK: %fast.no.md = fdiv fast <2 x float> <float 1.000000e+00, float 2.000000e+00>, %x{{$}}
+
+; CHECK: %[[X0:[0-9]+]] = extractelement <2 x float> %x, i64 0
+; CHECK: fdiv arcp float 1.000000e+00, %[[X0]], !fpmath !0
+; CHECK: %[[X1:[0-9]+]] = extractelement <2 x float> %x, i64 1
+; CHECK: fdiv arcp float 2.000000e+00, %[[X1]], !fpmath !0
+; CHECK: store volatile <2 x float> %arcp.25ulp
+
+; CHECK: %[[X0:[0-9]+]] = extractelement <2 x float> %x, i64 0
+; CHECK: fdiv fast float 1.000000e+00, %[[X0]], !fpmath !0
+; CHECK: %[[X1:[0-9]+]] = extractelement <2 x float> %x, i64 1
+; CHECK: fdiv fast float 2.000000e+00, %[[X1]], !fpmath !0
+; CHECK: store volatile <2 x float> %fast.25ulp
+define void @rcp_fdiv_fpmath_vector_nonsplat(<2 x float> addrspace(1)* %out, <2 x float> %x) #1 {
+ %no.md = fdiv <2 x float> <float 1.0, float 2.0>, %x
+ store volatile <2 x float> %no.md, <2 x float> addrspace(1)* %out
+
+ %arcp.no.md = fdiv arcp <2 x float> <float 1.0, float 2.0>, %x
+ store volatile <2 x float> %arcp.no.md, <2 x float> addrspace(1)* %out
+
+ %fast.no.md = fdiv fast <2 x float> <float 1.0, float 2.0>, %x
+ store volatile <2 x float> %fast.no.md, <2 x float> addrspace(1)* %out
+
+ %arcp.25ulp = fdiv arcp <2 x float> <float 1.0, float 2.0>, %x, !fpmath !0
+ store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out
+
+ %fast.25ulp = fdiv fast <2 x float> <float 1.0, float 2.0>, %x, !fpmath !0
+ store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out
+
+ ret void
+}
+
+; FIXME: Should be able to get fdiv for 1.0 component
+; CHECK-LABEL: @rcp_fdiv_fpmath_vector_partial_constant(
+; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0
+; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0
+; CHECK: store volatile <2 x float> %arcp.25ulp
+
+; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0
+; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %{{[0-9]+}}, float %{{[0-9]+}}), !fpmath !0
+; CHECK: store volatile <2 x float> %fast.25ulp
+define void @rcp_fdiv_fpmath_vector_partial_constant(<2 x float> addrspace(1)* %out, <2 x float> %x, <2 x float> %y) #1 {
+ %x.insert = insertelement <2 x float> %x, float 1.0, i32 0
+
+ %arcp.25ulp = fdiv arcp <2 x float> %x.insert, %y, !fpmath !0
+ store volatile <2 x float> %arcp.25ulp, <2 x float> addrspace(1)* %out
+
+ %fast.25ulp = fdiv fast <2 x float> %x.insert, %y, !fpmath !0
+ store volatile <2 x float> %fast.25ulp, <2 x float> addrspace(1)* %out
+
+ ret void
+}
+
+; CHECK-LABEL: @fdiv_fpmath_f32_denormals(
+; CHECK: %no.md = fdiv float %a, %b{{$}}
+; CHECK: %md.half.ulp = fdiv float %a, %b, !fpmath !1
+; CHECK: %md.1ulp = fdiv float %a, %b, !fpmath !2
+; CHECK: %md.25ulp = fdiv float %a, %b, !fpmath !0
+; CHECK: %md.3ulp = fdiv float %a, %b, !fpmath !3
+; CHECK: call fast float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
+; CHECK: call arcp float @llvm.amdgcn.fdiv.fast(float %a, float %b), !fpmath !0
+define void @fdiv_fpmath_f32_denormals(float addrspace(1)* %out, float %a, float %b) #2 {
+ %no.md = fdiv float %a, %b
+ store volatile float %no.md, float addrspace(1)* %out
+
+ %md.half.ulp = fdiv float %a, %b, !fpmath !1
+ store volatile float %md.half.ulp, float addrspace(1)* %out
+
+ %md.1ulp = fdiv float %a, %b, !fpmath !2
+ store volatile float %md.1ulp, float addrspace(1)* %out
+
+ %md.25ulp = fdiv float %a, %b, !fpmath !0
+ store volatile float %md.25ulp, float addrspace(1)* %out
+
+ %md.3ulp = fdiv float %a, %b, !fpmath !3
+ store volatile float %md.3ulp, float addrspace(1)* %out
+
+ %fast.md.25ulp = fdiv fast float %a, %b, !fpmath !0
+ store volatile float %fast.md.25ulp, float addrspace(1)* %out
+
+ %arcp.md.25ulp = fdiv arcp float %a, %b, !fpmath !0
+ store volatile float %arcp.md.25ulp, float addrspace(1)* %out
+
+ ret void
+}
+
+attributes #0 = { nounwind optnone noinline }
+attributes #1 = { nounwind }
+attributes #2 = { nounwind "target-features"="+fp32-denormals" }
+
+; CHECK: !0 = !{float 2.500000e+00}
+; CHECK: !1 = !{float 5.000000e-01}
+; CHECK: !2 = !{float 1.000000e+00}
+; CHECK: !3 = !{float 3.000000e+00}
+
+!0 = !{float 2.500000e+00}
+!1 = !{float 5.000000e-01}
+!2 = !{float 1.000000e+00}
+!3 = !{float 3.000000e+00}
diff --git a/test/CodeGen/AMDGPU/amdgpu.private-memory.ll b/test/CodeGen/AMDGPU/amdgpu.private-memory.ll
index 7b5158629091..bd0817d30413 100644
--- a/test/CodeGen/AMDGPU/amdgpu.private-memory.ll
+++ b/test/CodeGen/AMDGPU/amdgpu.private-memory.ll
@@ -417,12 +417,6 @@ entry:
ret void
}
-; HSAOPT: !0 = !{}
-; HSAOPT: !1 = !{i32 0, i32 2048}
-
-; NOHSAOPT: !0 = !{i32 0, i32 2048}
-
-
; FUNC-LABEL: v16i32_stack:
; R600: MOVA_INT
@@ -527,4 +521,33 @@ define void @v2float_stack(<2 x float> addrspace(1)* %out, i32 %a) {
ret void
}
+; OPT-LABEL: @direct_alloca_read_0xi32(
+; OPT: store [0 x i32] undef, [0 x i32] addrspace(3)*
+; OPT: load [0 x i32], [0 x i32] addrspace(3)*
+define void @direct_alloca_read_0xi32([0 x i32] addrspace(1)* %out, i32 %index) {
+entry:
+ %tmp = alloca [0 x i32]
+ store [0 x i32] [], [0 x i32]* %tmp
+ %load = load [0 x i32], [0 x i32]* %tmp
+ store [0 x i32] %load, [0 x i32] addrspace(1)* %out
+ ret void
+}
+
+; OPT-LABEL: @direct_alloca_read_1xi32(
+; OPT: store [1 x i32] zeroinitializer, [1 x i32] addrspace(3)*
+; OPT: load [1 x i32], [1 x i32] addrspace(3)*
+define void @direct_alloca_read_1xi32([1 x i32] addrspace(1)* %out, i32 %index) {
+entry:
+ %tmp = alloca [1 x i32]
+ store [1 x i32] [i32 0], [1 x i32]* %tmp
+ %load = load [1 x i32], [1 x i32]* %tmp
+ store [1 x i32] %load, [1 x i32] addrspace(1)* %out
+ ret void
+}
+
attributes #0 = { nounwind "amdgpu-max-waves-per-eu"="2" }
+
+; HSAOPT: !0 = !{}
+; HSAOPT: !1 = !{i32 0, i32 2048}
+
+; NOHSAOPT: !0 = !{i32 0, i32 2048}
diff --git a/test/CodeGen/AMDGPU/basic-branch.ll b/test/CodeGen/AMDGPU/basic-branch.ll
index ff730a085255..00636240bc6c 100644
--- a/test/CodeGen/AMDGPU/basic-branch.ll
+++ b/test/CodeGen/AMDGPU/basic-branch.ll
@@ -6,7 +6,6 @@
; GCN-LABEL: {{^}}test_branch:
; GCNNOOPT: v_writelane_b32
; GCNNOOPT: v_writelane_b32
-; GCNNOOPT: v_writelane_b32
; GCN: s_cbranch_scc1 [[END:BB[0-9]+_[0-9]+]]
; GCN: ; BB#1
diff --git a/test/CodeGen/AMDGPU/fdiv.ll b/test/CodeGen/AMDGPU/fdiv.ll
index 4021233e7785..65464cdba604 100644
--- a/test/CodeGen/AMDGPU/fdiv.ll
+++ b/test/CodeGen/AMDGPU/fdiv.ll
@@ -1,8 +1,4 @@
; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
-; RUN: llc -march=amdgcn -mcpu=tonga -mattr=+fp32-denormals -verify-machineinstrs < %s | FileCheck -check-prefix=I754 -check-prefix=FUNC %s
-; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs -amdgpu-fast-fdiv < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
-; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs < %s | FileCheck -check-prefix=I754 -check-prefix=FUNC %s
-; RUN: llc -march=amdgcn -mcpu=fiji -verify-machineinstrs -enable-unsafe-fp-math < %s | FileCheck -check-prefix=UNSAFE-FP -check-prefix=FUNC %s
; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck -check-prefix=R600 -check-prefix=FUNC %s
; These tests check that fdiv is expanded correctly and also test that the
@@ -15,22 +11,59 @@
; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[2].W
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].Z, PS
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_mul_f32_e32
+; SI: v_div_scale_f32
+; SI-DAG: v_div_scale_f32
; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
+; SI: v_fma_f32
+; SI: v_fma_f32
+; SI: v_mul_f32
+; SI: v_fma_f32
+; SI: v_fma_f32
+; SI: v_fma_f32
+; SI: v_div_fmas_f32
+; SI: v_div_fixup_f32
+define void @fdiv_f32(float addrspace(1)* %out, float %a, float %b) #0 {
+entry:
+ %fdiv = fdiv float %a, %b
+ store float %fdiv, float addrspace(1)* %out
+ ret void
+}
+
+; FUNC-LABEL: {{^}}fdiv_25ulp_f32:
+; SI: v_cndmask_b32
+; SI: v_mul_f32
+; SI: v_rcp_f32
+; SI: v_mul_f32
+; SI: v_mul_f32
+define void @fdiv_25ulp_f32(float addrspace(1)* %out, float %a, float %b) #0 {
+entry:
+ %fdiv = fdiv float %a, %b, !fpmath !0
+ store float %fdiv, float addrspace(1)* %out
+ ret void
+}
+
+; Use correct fdiv
+; FUNC-LABEL: {{^}}fdiv_25ulp_denormals_f32:
+; SI: v_fma_f32
+; SI: v_div_fmas_f32
+; SI: v_div_fixup_f32
+define void @fdiv_25ulp_denormals_f32(float addrspace(1)* %out, float %a, float %b) #2 {
+entry:
+ %fdiv = fdiv float %a, %b, !fpmath !0
+ store float %fdiv, float addrspace(1)* %out
+ ret void
+}
-; I754-DAG: v_div_scale_f32
-; I754-DAG: v_rcp_f32
-; I754-DAG: v_fma_f32
-; I754-DAG: v_mul_f32
-; I754-DAG: v_fma_f32
-; I754-DAG: v_div_fixup_f32
-define void @fdiv_f32(float addrspace(1)* %out, float %a, float %b) {
+; FUNC-LABEL: {{^}}fdiv_fast_denormals_f32:
+; SI: v_rcp_f32_e32 [[RCP:v[0-9]+]], s{{[0-9]+}}
+; SI: v_mul_f32_e32 [[RESULT:v[0-9]+]], s{{[0-9]+}}, [[RCP]]
+; SI-NOT: [[RESULT]]
+; SI: buffer_store_dword [[RESULT]]
+define void @fdiv_fast_denormals_f32(float addrspace(1)* %out, float %a, float %b) #2 {
entry:
- %0 = fdiv float %a, %b
- store float %0, float addrspace(1)* %out
+ %fdiv = fdiv fast float %a, %b
+ store float %fdiv, float addrspace(1)* %out
ret void
}
@@ -38,15 +71,14 @@ entry:
; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[2].W
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].Z, PS
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_mul_f32_e32
-
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-define void @fdiv_f32_fast_math(float addrspace(1)* %out, float %a, float %b) {
+; SI: v_rcp_f32_e32 [[RCP:v[0-9]+]], s{{[0-9]+}}
+; SI: v_mul_f32_e32 [[RESULT:v[0-9]+]], s{{[0-9]+}}, [[RCP]]
+; SI-NOT: [[RESULT]]
+; SI: buffer_store_dword [[RESULT]]
+define void @fdiv_f32_fast_math(float addrspace(1)* %out, float %a, float %b) #0 {
entry:
- %0 = fdiv fast float %a, %b
- store float %0, float addrspace(1)* %out
+ %fdiv = fdiv fast float %a, %b
+ store float %fdiv, float addrspace(1)* %out
ret void
}
@@ -54,15 +86,14 @@ entry:
; R600-DAG: RECIP_IEEE * T{{[0-9]+\.[XYZW]}}, KC0[2].W
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].Z, PS
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_mul_f32_e32
-
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-define void @fdiv_f32_arcp_math(float addrspace(1)* %out, float %a, float %b) {
+; SI: v_rcp_f32_e32 [[RCP:v[0-9]+]], s{{[0-9]+}}
+; SI: v_mul_f32_e32 [[RESULT:v[0-9]+]], s{{[0-9]+}}, [[RCP]]
+; SI-NOT: [[RESULT]]
+; SI: buffer_store_dword [[RESULT]]
+define void @fdiv_f32_arcp_math(float addrspace(1)* %out, float %a, float %b) #0 {
entry:
- %0 = fdiv arcp float %a, %b
- store float %0, float addrspace(1)* %out
+ %fdiv = fdiv arcp float %a, %b
+ store float %fdiv, float addrspace(1)* %out
ret void
}
@@ -72,26 +103,24 @@ entry:
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
+; SI: v_div_scale_f32
+; SI: v_div_scale_f32
+; SI: v_div_scale_f32
+; SI: v_div_scale_f32
+define void @fdiv_v2f32(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #0 {
+entry:
+ %fdiv = fdiv <2 x float> %a, %b
+ store <2 x float> %fdiv, <2 x float> addrspace(1)* %out
+ ret void
+}
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_fixup_f32
-; I754: v_div_fixup_f32
-define void @fdiv_v2f32(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) {
+; FUNC-LABEL: {{^}}fdiv_ulp25_v2f32:
+; SI: v_cmp_gt_f32
+; SI: v_cmp_gt_f32
+define void @fdiv_ulp25_v2f32(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #0 {
entry:
- %0 = fdiv <2 x float> %a, %b
- store <2 x float> %0, <2 x float> addrspace(1)* %out
+ %fdiv = fdiv arcp <2 x float> %a, %b, !fpmath !0
+ store <2 x float> %fdiv, <2 x float> addrspace(1)* %out
ret void
}
@@ -101,19 +130,12 @@ entry:
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-define void @fdiv_v2f32_fast_math(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) {
+; SI: v_rcp_f32
+; SI: v_rcp_f32
+define void @fdiv_v2f32_fast_math(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #0 {
entry:
- %0 = fdiv fast <2 x float> %a, %b
- store <2 x float> %0, <2 x float> addrspace(1)* %out
+ %fdiv = fdiv fast <2 x float> %a, %b
+ store <2 x float> %fdiv, <2 x float> addrspace(1)* %out
ret void
}
@@ -123,19 +145,12 @@ entry:
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[3].X, PS
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW]}}, KC0[2].W, PS
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_rcp_f32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-define void @fdiv_v2f32_arcp_math(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) {
+; SI: v_rcp_f32
+; SI: v_rcp_f32
+define void @fdiv_v2f32_arcp_math(<2 x float> addrspace(1)* %out, <2 x float> %a, <2 x float> %b) #0 {
entry:
- %0 = fdiv arcp <2 x float> %a, %b
- store <2 x float> %0, <2 x float> addrspace(1)* %out
+ %fdiv = fdiv arcp <2 x float> %a, %b
+ store <2 x float> %fdiv, <2 x float> addrspace(1)* %out
ret void
}
@@ -149,37 +164,11 @@ entry:
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_scale_f32
-; I754: v_div_fixup_f32
-; I754: v_div_fixup_f32
-; I754: v_div_fixup_f32
-; I754: v_div_fixup_f32
-define void @fdiv_v4f32(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) {
+; SI: v_div_fixup_f32
+; SI: v_div_fixup_f32
+; SI: v_div_fixup_f32
+; SI: v_div_fixup_f32
+define void @fdiv_v4f32(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) #0 {
%b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1
%a = load <4 x float>, <4 x float> addrspace(1) * %in
%b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr
@@ -198,24 +187,11 @@ define void @fdiv_v4f32(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-define void @fdiv_v4f32_fast_math(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) {
+; SI: v_rcp_f32
+; SI: v_rcp_f32
+; SI: v_rcp_f32
+; SI: v_rcp_f32
+define void @fdiv_v4f32_fast_math(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) #0 {
%b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1
%a = load <4 x float>, <4 x float> addrspace(1) * %in
%b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr
@@ -234,24 +210,11 @@ define void @fdiv_v4f32_fast_math(<4 x float> addrspace(1)* %out, <4 x float> ad
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
; R600-DAG: MUL_IEEE {{\** *}}T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}, PS
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_rcp_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-; UNSAFE-FP: v_mul_f32_e32
-
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-; SI-DAG: v_rcp_f32
-; SI-DAG: v_mul_f32
-define void @fdiv_v4f32_arcp_math(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) {
+; SI: v_rcp_f32
+; SI: v_rcp_f32
+; SI: v_rcp_f32
+; SI: v_rcp_f32
+define void @fdiv_v4f32_arcp_math(<4 x float> addrspace(1)* %out, <4 x float> addrspace(1)* %in) #0 {
%b_ptr = getelementptr <4 x float>, <4 x float> addrspace(1)* %in, i32 1
%a = load <4 x float>, <4 x float> addrspace(1) * %in
%b = load <4 x float>, <4 x float> addrspace(1) * %b_ptr
@@ -259,3 +222,9 @@ define void @fdiv_v4f32_arcp_math(<4 x float> addrspace(1)* %out, <4 x float> ad
store <4 x float> %result, <4 x float> addrspace(1)* %out
ret void
}
+
+attributes #0 = { nounwind "enable-unsafe-fp-math"="false" "target-features"="-fp32-denormals" }
+attributes #1 = { nounwind "enable-unsafe-fp-math"="true" "target-features"="-fp32-denormals" }
+attributes #2 = { nounwind "enable-unsafe-fp-math"="false" "target-features"="+fp32-denormals" }
+
+!0 = !{float 2.500000e+00}
diff --git a/test/CodeGen/AMDGPU/fp_to_sint.f64.ll b/test/CodeGen/AMDGPU/fp_to_sint.f64.ll
index be23e10d7087..1537d67cadcc 100644
--- a/test/CodeGen/AMDGPU/fp_to_sint.f64.ll
+++ b/test/CodeGen/AMDGPU/fp_to_sint.f64.ll
@@ -1,7 +1,8 @@
; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI -check-prefix=FUNC %s
; RUN: llc -march=amdgcn -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -check-prefix=CI -check-prefix=FUNC %s
-declare i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
+declare i32 @llvm.amdgcn.workitem.id.x() #1
+declare double @llvm.fabs.f64(double) #1
; FUNC-LABEL: @fp_to_sint_f64_i32
; SI: v_cvt_i32_f64_e32
@@ -54,3 +55,23 @@ define void @fp_to_sint_i64_f64(i64 addrspace(1)* %out, double addrspace(1)* %in
store i64 %cast, i64 addrspace(1)* %out, align 8
ret void
}
+
+; FUNC-LABEL: {{^}}fp_to_sint_f64_to_i1:
+; SI: v_cmp_eq_f64_e64 s{{\[[0-9]+:[0-9]+\]}}, -1.0, s{{\[[0-9]+:[0-9]+\]}}
+define void @fp_to_sint_f64_to_i1(i1 addrspace(1)* %out, double %in) #0 {
+ %conv = fptosi double %in to i1
+ store i1 %conv, i1 addrspace(1)* %out
+ ret void
+}
+
+; FUNC-LABEL: {{^}}fp_to_sint_fabs_f64_to_i1:
+; SI: v_cmp_eq_f64_e64 s{{\[[0-9]+:[0-9]+\]}}, -1.0, |s{{\[[0-9]+:[0-9]+\]}}|
+define void @fp_to_sint_fabs_f64_to_i1(i1 addrspace(1)* %out, double %in) #0 {
+ %in.fabs = call double @llvm.fabs.f64(double %in)
+ %conv = fptosi double %in.fabs to i1
+ store i1 %conv, i1 addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
diff --git a/test/CodeGen/AMDGPU/fp_to_sint.ll b/test/CodeGen/AMDGPU/fp_to_sint.ll
index b39aeadc8cce..0cd0358bafd5 100644
--- a/test/CodeGen/AMDGPU/fp_to_sint.ll
+++ b/test/CodeGen/AMDGPU/fp_to_sint.ll
@@ -2,7 +2,7 @@
; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck %s --check-prefix=SI --check-prefix=FUNC
; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck %s --check-prefix=EG --check-prefix=FUNC
-declare float @llvm.fabs.f32(float) #0
+declare float @llvm.fabs.f32(float) #1
; FUNC-LABEL: {{^}}fp_to_sint_i32:
; EG: FLT_TO_INT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
@@ -17,7 +17,7 @@ define void @fp_to_sint_i32(i32 addrspace(1)* %out, float %in) {
; FUNC-LABEL: {{^}}fp_to_sint_i32_fabs:
; SI: v_cvt_i32_f32_e64 v{{[0-9]+}}, |s{{[0-9]+}}|{{$}}
define void @fp_to_sint_i32_fabs(i32 addrspace(1)* %out, float %in) {
- %in.fabs = call float @llvm.fabs.f32(float %in) #0
+ %in.fabs = call float @llvm.fabs.f32(float %in)
%conv = fptosi float %in.fabs to i32
store i32 %conv, i32 addrspace(1)* %out
ret void
@@ -227,4 +227,26 @@ define void @fp_to_sint_v4i64(<4 x i64> addrspace(1)* %out, <4 x float> %x) {
ret void
}
-attributes #0 = { nounwind readnone }
+; FUNC-LABEL: {{^}}fp_to_uint_f32_to_i1:
+; SI: v_cmp_eq_f32_e64 s{{\[[0-9]+:[0-9]+\]}}, -1.0, s{{[0-9]+}}
+
+; EG: AND_INT
+; EG: SETE_DX10 {{[*]?}} T{{[0-9]+}}.{{[XYZW]}}, KC0[2].Z, literal.y,
+; EG-NEXT: -1082130432(-1.000000e+00)
+define void @fp_to_uint_f32_to_i1(i1 addrspace(1)* %out, float %in) #0 {
+ %conv = fptosi float %in to i1
+ store i1 %conv, i1 addrspace(1)* %out
+ ret void
+}
+
+; FUNC-LABEL: {{^}}fp_to_uint_fabs_f32_to_i1:
+; SI: v_cmp_eq_f32_e64 s{{\[[0-9]+:[0-9]+\]}}, -1.0, |s{{[0-9]+}}|
+define void @fp_to_uint_fabs_f32_to_i1(i1 addrspace(1)* %out, float %in) #0 {
+ %in.fabs = call float @llvm.fabs.f32(float %in)
+ %conv = fptosi float %in.fabs to i1
+ store i1 %conv, i1 addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
diff --git a/test/CodeGen/AMDGPU/fp_to_uint.f64.ll b/test/CodeGen/AMDGPU/fp_to_uint.f64.ll
index 760019ebdc08..d5bc416434df 100644
--- a/test/CodeGen/AMDGPU/fp_to_uint.f64.ll
+++ b/test/CodeGen/AMDGPU/fp_to_uint.f64.ll
@@ -1,7 +1,8 @@
; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=SI %s
; RUN: llc -march=amdgcn -mcpu=bonaire -verify-machineinstrs < %s | FileCheck -check-prefix=CI -check-prefix=FUNC %s
-declare i32 @llvm.amdgcn.workitem.id.x() nounwind readnone
+declare i32 @llvm.amdgcn.workitem.id.x() #1
+declare double @llvm.fabs.f64(double) #1
; SI-LABEL: {{^}}fp_to_uint_i32_f64:
; SI: v_cvt_u32_f64_e32
@@ -68,3 +69,23 @@ define void @fp_to_uint_v4i64_v4f64(<4 x i64> addrspace(1)* %out, <4 x double> %
store <4 x i64> %cast, <4 x i64> addrspace(1)* %out, align 32
ret void
}
+
+; FUNC-LABEL: {{^}}fp_to_uint_f64_to_i1:
+; SI: v_cmp_eq_f64_e64 s{{\[[0-9]+:[0-9]+\]}}, 1.0, s{{\[[0-9]+:[0-9]+\]}}
+define void @fp_to_uint_f64_to_i1(i1 addrspace(1)* %out, double %in) #0 {
+ %conv = fptoui double %in to i1
+ store i1 %conv, i1 addrspace(1)* %out
+ ret void
+}
+
+; FUNC-LABEL: {{^}}fp_to_uint_fabs_f64_to_i1:
+; SI: v_cmp_eq_f64_e64 s{{\[[0-9]+:[0-9]+\]}}, 1.0, |s{{\[[0-9]+:[0-9]+\]}}|
+define void @fp_to_uint_fabs_f64_to_i1(i1 addrspace(1)* %out, double %in) #0 {
+ %in.fabs = call double @llvm.fabs.f64(double %in)
+ %conv = fptoui double %in.fabs to i1
+ store i1 %conv, i1 addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
diff --git a/test/CodeGen/AMDGPU/fp_to_uint.ll b/test/CodeGen/AMDGPU/fp_to_uint.ll
index b7b6ccc238b3..8a0f9fa2ac2b 100644
--- a/test/CodeGen/AMDGPU/fp_to_uint.ll
+++ b/test/CodeGen/AMDGPU/fp_to_uint.ll
@@ -1,6 +1,8 @@
-; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck %s -check-prefix=EG -check-prefix=FUNC
-; RUN: llc -march=amdgcn -mcpu=SI -verify-machineinstrs < %s | FileCheck %s -check-prefix=SI -check-prefix=FUNC
+; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck %s -check-prefix=SI -check-prefix=FUNC
; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck %s -check-prefix=SI -check-prefix=FUNC
+; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck %s -check-prefix=EG -check-prefix=FUNC
+
+declare float @llvm.fabs.f32(float) #1
; FUNC-LABEL: {{^}}fp_to_uint_f32_to_i32:
; EG: FLT_TO_UINT {{\** *}}T{{[0-9]+\.[XYZW], PV\.[XYZW]}}
@@ -215,3 +217,27 @@ define void @fp_to_uint_v4f32_to_v4i64(<4 x i64> addrspace(1)* %out, <4 x float>
store <4 x i64> %conv, <4 x i64> addrspace(1)* %out
ret void
}
+
+
+; FUNC-LABEL: {{^}}fp_to_uint_f32_to_i1:
+; SI: v_cmp_eq_f32_e64 s{{\[[0-9]+:[0-9]+\]}}, 1.0, s{{[0-9]+}}
+
+; EG: AND_INT
+; EG: SETE_DX10 {{[*]?}} T{{[0-9]+}}.{{[XYZW]}}, KC0[2].Z, 1.0,
+define void @fp_to_uint_f32_to_i1(i1 addrspace(1)* %out, float %in) #0 {
+ %conv = fptoui float %in to i1
+ store i1 %conv, i1 addrspace(1)* %out
+ ret void
+}
+
+; FUNC-LABEL: {{^}}fp_to_uint_fabs_f32_to_i1:
+; SI: v_cmp_eq_f32_e64 s{{\[[0-9]+:[0-9]+\]}}, 1.0, |s{{[0-9]+}}|
+define void @fp_to_uint_fabs_f32_to_i1(i1 addrspace(1)* %out, float %in) #0 {
+ %in.fabs = call float @llvm.fabs.f32(float %in)
+ %conv = fptoui float %in.fabs to i1
+ store i1 %conv, i1 addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind }
+attributes #1 = { nounwind readnone }
diff --git a/test/CodeGen/AMDGPU/invalid-opencl-version-metadata1.ll b/test/CodeGen/AMDGPU/invalid-opencl-version-metadata1.ll
new file mode 100644
index 000000000000..4e17a921d91b
--- /dev/null
+++ b/test/CodeGen/AMDGPU/invalid-opencl-version-metadata1.ll
@@ -0,0 +1,8 @@
+; RUN: llc -mtriple=amdgcn--amdhsa < %s | FileCheck %s
+; check llc does not crash for invalid opencl version metadata
+
+; CHECK: .section .AMDGPU.runtime_metadata
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .short 256
+
+!opencl.ocl.version = !{}
diff --git a/test/CodeGen/AMDGPU/invalid-opencl-version-metadata2.ll b/test/CodeGen/AMDGPU/invalid-opencl-version-metadata2.ll
new file mode 100644
index 000000000000..35b7d70596c1
--- /dev/null
+++ b/test/CodeGen/AMDGPU/invalid-opencl-version-metadata2.ll
@@ -0,0 +1,9 @@
+; RUN: llc -mtriple=amdgcn--amdhsa < %s | FileCheck %s
+; check llc does not crash for invalid opencl version metadata
+
+; CHECK: .section .AMDGPU.runtime_metadata
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .short 256
+
+!opencl.ocl.version = !{!0}
+!0 = !{}
diff --git a/test/CodeGen/AMDGPU/invalid-opencl-version-metadata3.ll b/test/CodeGen/AMDGPU/invalid-opencl-version-metadata3.ll
new file mode 100644
index 000000000000..e1693551b621
--- /dev/null
+++ b/test/CodeGen/AMDGPU/invalid-opencl-version-metadata3.ll
@@ -0,0 +1,9 @@
+; RUN: llc -mtriple=amdgcn--amdhsa < %s | FileCheck %s
+; check llc does not crash for invalid opencl version metadata
+
+; CHECK: .section .AMDGPU.runtime_metadata
+; CHECK-NEXT: .byte 1
+; CHECK-NEXT: .short 256
+
+!opencl.ocl.version = !{!0}
+!0 = !{i32 1}
diff --git a/test/CodeGen/AMDGPU/llvm.amdgcn.fdiv.fast.ll b/test/CodeGen/AMDGPU/llvm.amdgcn.fdiv.fast.ll
new file mode 100644
index 000000000000..54d7848da3bf
--- /dev/null
+++ b/test/CodeGen/AMDGPU/llvm.amdgcn.fdiv.fast.ll
@@ -0,0 +1,18 @@
+; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck %s
+
+declare float @llvm.amdgcn.fdiv.fast(float, float) #0
+
+; CHECK-LABEL: {{^}}test_fdiv_fast:
+; CHECK: v_cndmask_b32_e32 v{{[0-9]+}}, 1.0, v{{[0-9]+}}, vcc
+; CHECK: v_mul_f32_e32
+; CHECK: v_rcp_f32_e32
+; CHECK: v_mul_f32_e32
+; CHECK: v_mul_f32_e32
+define void @test_fdiv_fast(float addrspace(1)* %out, float %a, float %b) #1 {
+ %fdiv = call float @llvm.amdgcn.fdiv.fast(float %a, float %b)
+ store float %fdiv, float addrspace(1)* %out
+ ret void
+}
+
+attributes #0 = { nounwind readnone }
+attributes #1 = { nounwind }
diff --git a/test/CodeGen/AMDGPU/llvm.amdgcn.groupstaticgroup.ll b/test/CodeGen/AMDGPU/llvm.amdgcn.groupstaticsize.ll
index cf6d1ab237cd..6014e2ed85f8 100644
--- a/test/CodeGen/AMDGPU/llvm.amdgcn.groupstaticgroup.ll
+++ b/test/CodeGen/AMDGPU/llvm.amdgcn.groupstaticsize.ll
@@ -2,13 +2,14 @@
; RUN: llc -mtriple=amdgcn--amdhsa -mcpu=kaveri -verify-machineinstrs < %s | FileCheck %s
; RUN: llc -mtriple=amdgcn--amdhsa -mcpu=fiji -verify-machineinstrs < %s | FileCheck %s
-
@lds0 = addrspace(3) global [512 x float] undef, align 4
@lds1 = addrspace(3) global [256 x float] undef, align 4
-; FUNC-LABEL: {{^}}groupstaticsize_test0:
-; CHECK: s_movk_i32 s{{[0-9]+}}, 0x800
-define void @get_groupstaticsize_test0(float addrspace(1)* %out, i32 addrspace(1)* %lds_size) #0 {
+@large = addrspace(3) global [4096 x i32] undef, align 4
+
+; CHECK-LABEL: {{^}}groupstaticsize_test0:
+; CHECK: v_mov_b32_e32 v{{[0-9]+}}, 0x800{{$}}
+define void @groupstaticsize_test0(float addrspace(1)* %out, i32 addrspace(1)* %lds_size) #0 {
%tid.x = tail call i32 @llvm.amdgcn.workitem.id.x() #1
%idx.0 = add nsw i32 %tid.x, 64
%static_lds_size = call i32 @llvm.amdgcn.groupstaticsize() #1
@@ -20,9 +21,8 @@ define void @get_groupstaticsize_test0(float addrspace(1)* %out, i32 addrspace(1
ret void
}
-
-; FUNC-LABEL: {{^}}groupstaticsize_test1:
-; CHECK: s_movk_i32 s{{[0-9]+}}, 0xc00
+; CHECK-LABEL: {{^}}groupstaticsize_test1:
+; CHECK: v_mov_b32_e32 v{{[0-9]+}}, 0xc00{{$}}
define void @groupstaticsize_test1(float addrspace(1)* %out, i32 %cond, i32 addrspace(1)* %lds_size) {
entry:
%static_lds_size = call i32 @llvm.amdgcn.groupstaticsize() #1
@@ -48,6 +48,16 @@ endif: ; preds = %else, %if
ret void
}
+; Exceeds 16-bit simm limit of s_movk_i32
+; CHECK-LABEL: {{^}}large_groupstaticsize:
+; CHECK: v_mov_b32_e32 [[REG:v[0-9]+]], 0x4000{{$}}
+define void @large_groupstaticsize(i32 addrspace(1)* %size, i32 %idx) #0 {
+ %gep = getelementptr inbounds [4096 x i32], [4096 x i32] addrspace(3)* @large, i32 0, i32 %idx
+ store volatile i32 0, i32 addrspace(3)* %gep
+ %static_lds_size = call i32 @llvm.amdgcn.groupstaticsize()
+ store i32 %static_lds_size, i32 addrspace(1)* %size
+ ret void
+}
declare i32 @llvm.amdgcn.groupstaticsize() #1
declare i32 @llvm.amdgcn.workitem.id.x() #1
diff --git a/test/CodeGen/AMDGPU/rcp-pattern.ll b/test/CodeGen/AMDGPU/rcp-pattern.ll
index b1d422062543..27a88f7b59e7 100644
--- a/test/CodeGen/AMDGPU/rcp-pattern.ll
+++ b/test/CodeGen/AMDGPU/rcp-pattern.ll
@@ -1,11 +1,96 @@
-; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs < %s | FileCheck -check-prefix=EG-SAFE -check-prefix=FUNC %s
+; RUN: llc -march=amdgcn -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s
+; RUN: llc -march=amdgcn -mcpu=tonga -verify-machineinstrs < %s | FileCheck -check-prefix=GCN -check-prefix=FUNC %s
+; RUN: llc -march=r600 -mcpu=cypress -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
; RUN: llc -march=r600 -mcpu=cayman -verify-machineinstrs < %s | FileCheck -check-prefix=EG -check-prefix=FUNC %s
-; FIXME: Evergreen only ever does unsafe fp math.
; FUNC-LABEL: {{^}}rcp_pat_f32:
+; GCN: s_load_dword [[SRC:s[0-9]+]]
+; GCN: v_rcp_f32_e32 [[RCP:v[0-9]+]], [[SRC]]
+; GCN: buffer_store_dword [[RCP]]
+
; EG: RECIP_IEEE
-define void @rcp_pat_f32(float addrspace(1)* %out, float %src) nounwind {
+define void @rcp_pat_f32(float addrspace(1)* %out, float %src) #0 {
%rcp = fdiv float 1.0, %src
store float %rcp, float addrspace(1)* %out, align 4
ret void
}
+
+; FUNC-LABEL: {{^}}rcp_ulp25_pat_f32:
+; GCN: s_load_dword [[SRC:s[0-9]+]]
+; GCN: v_rcp_f32_e32 [[RCP:v[0-9]+]], [[SRC]]
+; GCN: buffer_store_dword [[RCP]]
+
+; EG: RECIP_IEEE
+define void @rcp_ulp25_pat_f32(float addrspace(1)* %out, float %src) #0 {
+ %rcp = fdiv float 1.0, %src, !fpmath !0
+ store float %rcp, float addrspace(1)* %out, align 4
+ ret void
+}
+
+; FUNC-LABEL: {{^}}rcp_fast_ulp25_pat_f32:
+; GCN: s_load_dword [[SRC:s[0-9]+]]
+; GCN: v_rcp_f32_e32 [[RCP:v[0-9]+]], [[SRC]]
+; GCN: buffer_store_dword [[RCP]]
+
+; EG: RECIP_IEEE
+define void @rcp_fast_ulp25_pat_f32(float addrspace(1)* %out, float %src) #0 {
+ %rcp = fdiv fast float 1.0, %src, !fpmath !0
+ store float %rcp, float addrspace(1)* %out, align 4
+ ret void
+}
+
+; FUNC-LABEL: {{^}}rcp_arcp_ulp25_pat_f32:
+; GCN: s_load_dword [[SRC:s[0-9]+]]
+; GCN: v_rcp_f32_e32 [[RCP:v[0-9]+]], [[SRC]]
+; GCN: buffer_store_dword [[RCP]]
+
+; EG: RECIP_IEEE
+define void @rcp_arcp_ulp25_pat_f32(float addrspace(1)* %out, float %src) #0 {
+ %rcp = fdiv arcp float 1.0, %src, !fpmath !0
+ store float %rcp, float addrspace(1)* %out, align 4
+ ret void
+}
+
+; FUNC-LABEL: {{^}}rcp_global_fast_ulp25_pat_f32:
+; GCN: s_load_dword [[SRC:s[0-9]+]]
+; GCN: v_rcp_f32_e32 [[RCP:v[0-9]+]], [[SRC]]
+; GCN: buffer_store_dword [[RCP]]
+
+; EG: RECIP_IEEE
+define void @rcp_global_fast_ulp25_pat_f32(float addrspace(1)* %out, float %src) #2 {
+ %rcp = fdiv float 1.0, %src, !fpmath !0
+ store float %rcp, float addrspace(1)* %out, align 4
+ ret void
+}
+
+; FUNC-LABEL: {{^}}rcp_fabs_pat_f32:
+; GCN: s_load_dword [[SRC:s[0-9]+]]
+; GCN: v_rcp_f32_e64 [[RCP:v[0-9]+]], |[[SRC]]|
+; GCN: buffer_store_dword [[RCP]]
+
+; EG: RECIP_IEEE
+define void @rcp_fabs_pat_f32(float addrspace(1)* %out, float %src) #0 {
+ %src.fabs = call float @llvm.fabs.f32(float %src)
+ %rcp = fdiv float 1.0, %src.fabs
+ store float %rcp, float addrspace(1)* %out, align 4
+ ret void
+}
+
+; FIXME: fneg folded into constant 1
+; FUNC-LABEL: {{^}}rcp_fabs_fneg_pat_f32:
+define void @rcp_fabs_fneg_pat_f32(float addrspace(1)* %out, float %src) #0 {
+ %src.fabs = call float @llvm.fabs.f32(float %src)
+ %src.fabs.fneg = fsub float -0.0, %src.fabs
+ %rcp = fdiv float 1.0, %src.fabs.fneg
+ store float %rcp, float addrspace(1)* %out, align 4
+ ret void
+}
+
+
+declare float @llvm.fabs.f32(float) #1
+
+attributes #0 = { nounwind "unsafe-fp-math"="false" }
+attributes #1 = { nounwind readnone }
+attributes #2 = { nounwind "unsafe-fp-math"="true" }
+
+!0 = !{float 2.500000e+00}
diff --git a/test/CodeGen/AMDGPU/reciprocal.ll b/test/CodeGen/AMDGPU/reciprocal.ll
deleted file mode 100644
index f9292a788521..000000000000
--- a/test/CodeGen/AMDGPU/reciprocal.ll
+++ /dev/null
@@ -1,13 +0,0 @@
-;RUN: llc < %s -march=r600 -mcpu=redwood | FileCheck %s
-
-;CHECK: RECIP_IEEE * T{{[0-9]+\.[XYZW], T[0-9]+\.[XYZW]}}
-
-define amdgpu_ps void @test(<4 x float> inreg %reg0) {
- %r0 = extractelement <4 x float> %reg0, i32 0
- %r1 = fdiv float 1.0, %r0
- %vec = insertelement <4 x float> undef, float %r1, i32 0
- call void @llvm.r600.store.swizzle(<4 x float> %vec, i32 0, i32 0)
- ret void
-}
-
-declare void @llvm.r600.store.swizzle(<4 x float>, i32, i32)
diff --git a/test/CodeGen/AMDGPU/skip-if-dead.ll b/test/CodeGen/AMDGPU/skip-if-dead.ll
index 10187f6125d6..4ba4ac76a280 100644
--- a/test/CodeGen/AMDGPU/skip-if-dead.ll
+++ b/test/CodeGen/AMDGPU/skip-if-dead.ll
@@ -348,7 +348,6 @@ bb7: ; preds = %bb4
; CHECK: image_sample_c
; CHECK: v_cmp_neq_f32_e32 vcc, 0,
-; CHECK: s_and_b64 exec, exec,
; CHECK: s_and_saveexec_b64 s{{\[[0-9]+:[0-9]+\]}}, vcc
; CHECK: s_xor_b64 s{{\[[0-9]+:[0-9]+\]}}, exec
; CHECK: mask branch [[END:BB[0-9]+_[0-9]+]]
@@ -385,6 +384,7 @@ bb9: ; preds = %bb4
declare void @llvm.AMDGPU.kill(float) #0
declare <4 x float> @llvm.SI.image.sample.c.v4i32(<4 x i32>, <8 x i32>, <4 x i32>, i32, i32, i32, i32, i32, i32, i32, i32) #1
+declare void @llvm.amdgcn.buffer.store.f32(float, <4 x i32>, i32, i32, i1, i1) nounwind
attributes #0 = { nounwind }
attributes #1 = { nounwind readnone } \ No newline at end of file
diff --git a/test/CodeGen/AMDGPU/vector-alloca.ll b/test/CodeGen/AMDGPU/vector-alloca.ll
index c151ca9ef9b4..7dcf36f144ac 100644
--- a/test/CodeGen/AMDGPU/vector-alloca.ll
+++ b/test/CodeGen/AMDGPU/vector-alloca.ll
@@ -3,6 +3,11 @@
; RUN: llc -march=amdgcn -mcpu=tonga -mattr=-promote-alloca -verify-machineinstrs < %s | FileCheck -check-prefix=SI-ALLOCA -check-prefix=SI -check-prefix=FUNC %s
; RUN: llc -march=amdgcn -mcpu=tonga -mattr=+promote-alloca -verify-machineinstrs < %s | FileCheck -check-prefix=SI-PROMOTE -check-prefix=SI -check-prefix=FUNC %s
; RUN: llc -march=r600 -mcpu=redwood < %s | FileCheck --check-prefix=EG -check-prefix=FUNC %s
+; RUN: opt -S -mtriple=amdgcn-- -amdgpu-promote-alloca -sroa -instcombine < %s | FileCheck -check-prefix=OPT %s
+
+; OPT-LABEL: @vector_read(
+; OPT: %0 = extractelement <4 x i32> <i32 0, i32 1, i32 2, i32 3>, i32 %index
+; OPT: store i32 %0, i32 addrspace(1)* %out, align 4
; FUNC-LABEL: {{^}}vector_read:
; EG: MOV
@@ -12,21 +17,26 @@
; EG: MOVA_INT
define void @vector_read(i32 addrspace(1)* %out, i32 %index) {
entry:
- %0 = alloca [4 x i32]
- %x = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 0
- %y = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 1
- %z = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 2
- %w = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 3
+ %tmp = alloca [4 x i32]
+ %x = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 0
+ %y = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 1
+ %z = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 2
+ %w = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 3
store i32 0, i32* %x
store i32 1, i32* %y
store i32 2, i32* %z
store i32 3, i32* %w
- %1 = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 %index
- %2 = load i32, i32* %1
- store i32 %2, i32 addrspace(1)* %out
+ %tmp1 = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 %index
+ %tmp2 = load i32, i32* %tmp1
+ store i32 %tmp2, i32 addrspace(1)* %out
ret void
}
+; OPT-LABEL: @vector_write(
+; OPT: %0 = insertelement <4 x i32> zeroinitializer, i32 1, i32 %w_index
+; OPT: %1 = extractelement <4 x i32> %0, i32 %r_index
+; OPT: store i32 %1, i32 addrspace(1)* %out, align 4
+
; FUNC-LABEL: {{^}}vector_write:
; EG: MOV
; EG: MOV
@@ -36,42 +46,95 @@ entry:
; EG: MOVA_INT
define void @vector_write(i32 addrspace(1)* %out, i32 %w_index, i32 %r_index) {
entry:
- %0 = alloca [4 x i32]
- %x = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 0
- %y = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 1
- %z = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 2
- %w = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 3
+ %tmp = alloca [4 x i32]
+ %x = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 0
+ %y = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 1
+ %z = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 2
+ %w = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 3
store i32 0, i32* %x
store i32 0, i32* %y
store i32 0, i32* %z
store i32 0, i32* %w
- %1 = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 %w_index
- store i32 1, i32* %1
- %2 = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 %r_index
- %3 = load i32, i32* %2
- store i32 %3, i32 addrspace(1)* %out
+ %tmp1 = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 %w_index
+ store i32 1, i32* %tmp1
+ %tmp2 = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 %r_index
+ %tmp3 = load i32, i32* %tmp2
+ store i32 %tmp3, i32 addrspace(1)* %out
ret void
}
; This test should be optimize to:
; store i32 0, i32 addrspace(1)* %out
+
+; OPT-LABEL: @bitcast_gep(
+; OPT-LABEL: store i32 0, i32 addrspace(1)* %out, align 4
+
; FUNC-LABEL: {{^}}bitcast_gep:
; EG: STORE_RAW
define void @bitcast_gep(i32 addrspace(1)* %out, i32 %w_index, i32 %r_index) {
entry:
- %0 = alloca [4 x i32]
- %x = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 0
- %y = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 1
- %z = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 2
- %w = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 3
+ %tmp = alloca [4 x i32]
+ %x = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 0
+ %y = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 1
+ %z = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 2
+ %w = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 3
store i32 0, i32* %x
store i32 0, i32* %y
store i32 0, i32* %z
store i32 0, i32* %w
- %1 = getelementptr [4 x i32], [4 x i32]* %0, i32 0, i32 1
- %2 = bitcast i32* %1 to [4 x i32]*
- %3 = getelementptr [4 x i32], [4 x i32]* %2, i32 0, i32 0
- %4 = load i32, i32* %3
- store i32 %4, i32 addrspace(1)* %out
+ %tmp1 = getelementptr [4 x i32], [4 x i32]* %tmp, i32 0, i32 1
+ %tmp2 = bitcast i32* %tmp1 to [4 x i32]*
+ %tmp3 = getelementptr [4 x i32], [4 x i32]* %tmp2, i32 0, i32 0
+ %tmp4 = load i32, i32* %tmp3
+ store i32 %tmp4, i32 addrspace(1)* %out
+ ret void
+}
+
+; OPT-LABEL: @vector_read_bitcast_gep(
+; OPT: %0 = extractelement <4 x i32> <i32 1065353216, i32 1, i32 2, i32 3>, i32 %index
+; OPT: store i32 %0, i32 addrspace(1)* %out, align 4
+define void @vector_read_bitcast_gep(i32 addrspace(1)* %out, i32 %index) {
+entry:
+ %tmp = alloca [4 x i32]
+ %x = getelementptr inbounds [4 x i32], [4 x i32]* %tmp, i32 0, i32 0
+ %y = getelementptr inbounds [4 x i32], [4 x i32]* %tmp, i32 0, i32 1
+ %z = getelementptr inbounds [4 x i32], [4 x i32]* %tmp, i32 0, i32 2
+ %w = getelementptr inbounds [4 x i32], [4 x i32]* %tmp, i32 0, i32 3
+ %bc = bitcast i32* %x to float*
+ store float 1.0, float* %bc
+ store i32 1, i32* %y
+ store i32 2, i32* %z
+ store i32 3, i32* %w
+ %tmp1 = getelementptr inbounds [4 x i32], [4 x i32]* %tmp, i32 0, i32 %index
+ %tmp2 = load i32, i32* %tmp1
+ store i32 %tmp2, i32 addrspace(1)* %out
+ ret void
+}
+
+; FIXME: Should be able to promote this. Instcombine should fold the
+; cast in the hasOneUse case so it might not matter in practice
+
+; OPT-LABEL: @vector_read_bitcast_alloca(
+; OPT: alloca [4 x float]
+; OPT: store float
+; OPT: store float
+; OPT: store float
+; OPT: store float
+; OPT: load float
+define void @vector_read_bitcast_alloca(float addrspace(1)* %out, i32 %index) {
+entry:
+ %tmp = alloca [4 x i32]
+ %tmp.bc = bitcast [4 x i32]* %tmp to [4 x float]*
+ %x = getelementptr inbounds [4 x float], [4 x float]* %tmp.bc, i32 0, i32 0
+ %y = getelementptr inbounds [4 x float], [4 x float]* %tmp.bc, i32 0, i32 1
+ %z = getelementptr inbounds [4 x float], [4 x float]* %tmp.bc, i32 0, i32 2
+ %w = getelementptr inbounds [4 x float], [4 x float]* %tmp.bc, i32 0, i32 3
+ store float 0.0, float* %x
+ store float 1.0, float* %y
+ store float 2.0, float* %z
+ store float 4.0, float* %w
+ %tmp1 = getelementptr inbounds [4 x float], [4 x float]* %tmp.bc, i32 0, i32 %index
+ %tmp2 = load float, float* %tmp1
+ store float %tmp2, float addrspace(1)* %out
ret void
}
diff --git a/test/CodeGen/AMDGPU/wqm.ll b/test/CodeGen/AMDGPU/wqm.ll
index 23b0ffd5b3da..809a7ba9b826 100644
--- a/test/CodeGen/AMDGPU/wqm.ll
+++ b/test/CodeGen/AMDGPU/wqm.ll
@@ -41,14 +41,14 @@ main_body:
;CHECK: store
;CHECK-NOT: exec
;CHECK: .size test3
-define amdgpu_ps <4 x float> @test3(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, <4 x i32> %c) {
+define amdgpu_ps <4 x float> @test3(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, <4 x i32> %c) {
main_body:
%tex = call <4 x float> @llvm.SI.image.sample.v4i32(<4 x i32> %c, <8 x i32> %rsrc, <4 x i32> %sampler, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
%tex.1 = bitcast <4 x float> %tex to <4 x i32>
%tex.2 = extractelement <4 x i32> %tex.1, i32 0
- %gep = getelementptr float, float addrspace(1)* %ptr, i32 %tex.2
- %wr = extractelement <4 x float> %tex, i32 1
- store float %wr, float addrspace(1)* %gep
+
+ call void @llvm.amdgcn.buffer.store.v4f32(<4 x float> %tex, <4 x i32> undef, i32 %tex.2, i32 0, i1 0, i1 0)
+
ret <4 x float> %tex
}
@@ -66,8 +66,9 @@ main_body:
define amdgpu_ps <4 x float> @test4(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, i32 %c, i32 %d, float %data) {
main_body:
%c.1 = mul i32 %c, %d
- %gep = getelementptr float, float addrspace(1)* %ptr, i32 %c.1
- store float %data, float addrspace(1)* %gep
+
+ call void @llvm.amdgcn.buffer.store.v4f32(<4 x float> undef, <4 x i32> undef, i32 %c.1, i32 0, i1 0, i1 0)
+
%tex = call <4 x float> @llvm.SI.image.sample.i32(i32 %c.1, <8 x i32> %rsrc, <4 x i32> %sampler, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
ret <4 x float> %tex
}
@@ -89,7 +90,7 @@ main_body:
;CHECK: s_mov_b64 exec, [[SAVED]]
;CHECK: %IF
;CHECK: image_sample
-define amdgpu_ps float @test_control_flow_0(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, i32 %c, i32 %z, float %data) {
+define amdgpu_ps float @test_control_flow_0(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, i32 %c, i32 %z, float %data) {
main_body:
%cmp = icmp eq i32 %z, 0
br i1 %cmp, label %IF, label %ELSE
@@ -100,8 +101,7 @@ IF:
br label %END
ELSE:
- %gep = getelementptr float, float addrspace(1)* %ptr, i32 %c
- store float %data, float addrspace(1)* %gep
+ call void @llvm.amdgcn.buffer.store.f32(float %data, <4 x i32> undef, i32 %c, i32 0, i1 0, i1 0)
br label %END
END:
@@ -129,7 +129,7 @@ END:
;CHECK: s_or_b64 exec, exec,
;CHECK: v_mov_b32_e32 v0
;CHECK: ; return
-define amdgpu_ps float @test_control_flow_1(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, i32 %c, i32 %z, float %data) {
+define amdgpu_ps float @test_control_flow_1(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, i32 %c, i32 %z, float %data) {
main_body:
%cmp = icmp eq i32 %z, 0
br i1 %cmp, label %ELSE, label %IF
@@ -140,8 +140,7 @@ IF:
br label %END
ELSE:
- %gep = getelementptr float, float addrspace(1)* %ptr, i32 %c
- store float %data, float addrspace(1)* %gep
+ call void @llvm.amdgcn.buffer.store.f32(float %data, <4 x i32> undef, i32 %c, i32 0, i1 0, i1 0)
br label %END
END:
@@ -163,23 +162,20 @@ END:
;CHECK: store
;CHECK: s_wqm_b64 exec, exec
;CHECK: v_cmp
-define amdgpu_ps <4 x float> @test_control_flow_2(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, <3 x i32> %idx, <2 x float> %data, i32 %coord) {
+define amdgpu_ps <4 x float> @test_control_flow_2(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, <3 x i32> %idx, <2 x float> %data, i32 %coord) {
main_body:
%idx.1 = extractelement <3 x i32> %idx, i32 0
- %gep.1 = getelementptr float, float addrspace(1)* %ptr, i32 %idx.1
%data.1 = extractelement <2 x float> %data, i32 0
- store float %data.1, float addrspace(1)* %gep.1
+ call void @llvm.amdgcn.buffer.store.f32(float %data.1, <4 x i32> undef, i32 %idx.1, i32 0, i1 0, i1 0)
; The load that determines the branch (and should therefore be WQM) is
; surrounded by stores that require disabled WQM.
%idx.2 = extractelement <3 x i32> %idx, i32 1
- %gep.2 = getelementptr float, float addrspace(1)* %ptr, i32 %idx.2
- %z = load float, float addrspace(1)* %gep.2
+ %z = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> undef, i32 %idx.2, i32 0, i1 0, i1 0)
%idx.3 = extractelement <3 x i32> %idx, i32 2
- %gep.3 = getelementptr float, float addrspace(1)* %ptr, i32 %idx.3
%data.3 = extractelement <2 x float> %data, i32 1
- store float %data.3, float addrspace(1)* %gep.3
+ call void @llvm.amdgcn.buffer.store.f32(float %data.3, <4 x i32> undef, i32 %idx.3, i32 0, i1 0, i1 0)
%cc = fcmp ogt float %z, 0.0
br i1 %cc, label %IF, label %ELSE
@@ -210,24 +206,21 @@ END:
;CHECK: load
;CHECK: store
;CHECK: v_cmp
-define amdgpu_ps float @test_control_flow_3(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, <3 x i32> %idx, <2 x float> %data, i32 %coord) {
+define amdgpu_ps float @test_control_flow_3(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, <3 x i32> %idx, <2 x float> %data, i32 %coord) {
main_body:
%tex = call <4 x float> @llvm.SI.image.sample.i32(i32 %coord, <8 x i32> %rsrc, <4 x i32> %sampler, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
%tex.1 = extractelement <4 x float> %tex, i32 0
%idx.1 = extractelement <3 x i32> %idx, i32 0
- %gep.1 = getelementptr float, float addrspace(1)* %ptr, i32 %idx.1
%data.1 = extractelement <2 x float> %data, i32 0
- store float %data.1, float addrspace(1)* %gep.1
+ call void @llvm.amdgcn.buffer.store.f32(float %data.1, <4 x i32> undef, i32 %idx.1, i32 0, i1 0, i1 0)
%idx.2 = extractelement <3 x i32> %idx, i32 1
- %gep.2 = getelementptr float, float addrspace(1)* %ptr, i32 %idx.2
- %z = load float, float addrspace(1)* %gep.2
+ %z = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> undef, i32 %idx.2, i32 0, i1 0, i1 0)
%idx.3 = extractelement <3 x i32> %idx, i32 2
- %gep.3 = getelementptr float, float addrspace(1)* %ptr, i32 %idx.3
%data.3 = extractelement <2 x float> %data, i32 1
- store float %data.3, float addrspace(1)* %gep.3
+ call void @llvm.amdgcn.buffer.store.f32(float %data.3, <4 x i32> undef, i32 %idx.3, i32 0, i1 0, i1 0)
%cc = fcmp ogt float %z, 0.0
br i1 %cc, label %IF, label %ELSE
@@ -258,15 +251,14 @@ END:
;CHECK: s_mov_b64 exec, [[SAVE]]
;CHECK: %END
;CHECK: image_sample
-define amdgpu_ps <4 x float> @test_control_flow_4(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, i32 %coord, i32 %y, float %z) {
+define amdgpu_ps <4 x float> @test_control_flow_4(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, i32 %coord, i32 %y, float %z) {
main_body:
%cond = icmp eq i32 %y, 0
br i1 %cond, label %IF, label %END
IF:
- %data = load float, float addrspace(1)* %ptr
- %gep = getelementptr float, float addrspace(1)* %ptr, i32 1
- store float %data, float addrspace(1)* %gep
+ %data = call float @llvm.amdgcn.buffer.load.f32(<4 x i32> undef, i32 0, i32 0, i1 0, i1 0)
+ call void @llvm.amdgcn.buffer.store.f32(float %data, <4 x i32> undef, i32 1, i32 0, i1 0, i1 0)
br label %END
END:
@@ -282,13 +274,11 @@ END:
;CHECK-NEXT: s_wqm_b64 exec, exec
;CHECK: image_sample
;CHECK: s_and_b64 exec, exec, [[ORIG]]
-;SI: buffer_store_dword
-;VI: flat_store_dword
+;CHECK: buffer_store_dword
;CHECK: s_wqm_b64 exec, exec
;CHECK: v_cmpx_
;CHECK: s_and_saveexec_b64 [[SAVE:s\[[0-9]+:[0-9]+\]]], [[ORIG]]
-;SI: buffer_store_dword
-;VI: flat_store_dword
+;CHECK: buffer_store_dword
;CHECK: s_mov_b64 exec, [[SAVE]]
;CHECK: image_sample
define amdgpu_ps <4 x float> @test_kill_0(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, <2 x i32> %idx, <2 x float> %data, i32 %coord, i32 %coord2, float %z) {
@@ -296,16 +286,14 @@ main_body:
%tex = call <4 x float> @llvm.SI.image.sample.i32(i32 %coord, <8 x i32> %rsrc, <4 x i32> %sampler, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
%idx.0 = extractelement <2 x i32> %idx, i32 0
- %gep.0 = getelementptr float, float addrspace(1)* %ptr, i32 %idx.0
%data.0 = extractelement <2 x float> %data, i32 0
- store float %data.0, float addrspace(1)* %gep.0
+ call void @llvm.amdgcn.buffer.store.f32(float %data.0, <4 x i32> undef, i32 %idx.0, i32 0, i1 0, i1 0)
call void @llvm.AMDGPU.kill(float %z)
%idx.1 = extractelement <2 x i32> %idx, i32 1
- %gep.1 = getelementptr float, float addrspace(1)* %ptr, i32 %idx.1
%data.1 = extractelement <2 x float> %data, i32 1
- store float %data.1, float addrspace(1)* %gep.1
+ call void @llvm.amdgcn.buffer.store.f32(float %data.1, <4 x i32> undef, i32 %idx.1, i32 0, i1 0, i1 0)
%tex2 = call <4 x float> @llvm.SI.image.sample.i32(i32 %coord2, <8 x i32> %rsrc, <4 x i32> %sampler, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
%out = fadd <4 x float> %tex, %tex2
@@ -321,16 +309,14 @@ main_body:
; CHECK: s_wqm_b64 exec, exec
; CHECK: image_sample
; CHECK: s_and_b64 exec, exec, [[ORIG]]
-; SI: buffer_store_dword
-; VI: flat_store_dword
+; CHECK: buffer_store_dword
; CHECK-NOT: wqm
; CHECK: v_cmpx_
-define amdgpu_ps <4 x float> @test_kill_1(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, float addrspace(1)* inreg %ptr, i32 %idx, float %data, i32 %coord, i32 %coord2, float %z) {
+define amdgpu_ps <4 x float> @test_kill_1(<8 x i32> inreg %rsrc, <4 x i32> inreg %sampler, i32 %idx, float %data, i32 %coord, i32 %coord2, float %z) {
main_body:
%tex = call <4 x float> @llvm.SI.image.sample.i32(i32 %coord, <8 x i32> %rsrc, <4 x i32> %sampler, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
- %gep = getelementptr float, float addrspace(1)* %ptr, i32 %idx
- store float %data, float addrspace(1)* %gep
+ call void @llvm.amdgcn.buffer.store.f32(float %data, <4 x i32> undef, i32 0, i32 0, i1 0, i1 0)
call void @llvm.AMDGPU.kill(float %z)
@@ -350,9 +336,91 @@ main_body:
ret float %s
}
+; CHECK-LABEL: {{^}}test_loop_vcc:
+; CHECK-NEXT: ; %entry
+; CHECK-NEXT: s_mov_b64 [[LIVE:s\[[0-9]+:[0-9]+\]]], exec
+; CHECK: s_wqm_b64 exec, exec
+; CHECK: s_and_b64 exec, exec, [[LIVE]]
+; CHECK: image_store
+; CHECK: s_wqm_b64 exec, exec
+; CHECK: v_mov_b32_e32 [[CTR:v[0-9]+]], -2
+; CHECK: s_branch [[LOOPHDR:BB[0-9]+_[0-9]+]]
+
+; CHECK: [[LOOPHDR]]: ; %loop
+; CHECK: v_add_i32_e32 [[CTR]], vcc, 2, [[CTR]]
+; CHECK: v_cmp_lt_i32_e32 vcc, 7, [[CTR]]
+; CHECK: s_cbranch_vccz
+; CHECK: ; %break
+
+; CHECK: ; return
+define amdgpu_ps <4 x float> @test_loop_vcc(<4 x float> %in) nounwind {
+entry:
+ call void @llvm.amdgcn.image.store.v4i32(<4 x float> %in, <4 x i32> undef, <8 x i32> undef, i32 15, i1 0, i1 0, i1 0, i1 0)
+ br label %loop
+
+loop:
+ %ctr.iv = phi i32 [ 0, %entry ], [ %ctr.next, %body ]
+ %c.iv = phi <4 x float> [ %in, %entry ], [ %c.next, %body ]
+ %cc = icmp sgt i32 %ctr.iv, 7
+ br i1 %cc, label %break, label %body
+
+body:
+ %c.i = bitcast <4 x float> %c.iv to <4 x i32>
+ %c.next = call <4 x float> @llvm.SI.image.sample.v4i32(<4 x i32> %c.i, <8 x i32> undef, <4 x i32> undef, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
+ %ctr.next = add i32 %ctr.iv, 2
+ br label %loop
+
+break:
+ ret <4 x float> %c.iv
+}
+
+; Only intrinsic stores need exact execution -- other stores do not have
+; externally visible effects and may require WQM for correctness.
+;
+; CHECK-LABEL: {{^}}test_alloca:
+; CHECK: s_mov_b64 [[LIVE:s\[[0-9]+:[0-9]+\]]], exec
+; CHECK: s_wqm_b64 exec, exec
+
+; CHECK: s_and_b64 exec, exec, [[LIVE]]
+; CHECK: buffer_store_dword {{v[0-9]+}}, off, {{s\[[0-9]+:[0-9]+\]}}, 0
+; CHECK: s_wqm_b64 exec, exec
+; CHECK: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen
+; CHECK: s_and_b64 exec, exec, [[LIVE]]
+; CHECK: buffer_store_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, 0 idxen
+; CHECK: s_wqm_b64 exec, exec
+; CHECK: buffer_load_dword {{v[0-9]+}}, {{v[0-9]+}}, {{s\[[0-9]+:[0-9]+\]}}, {{s[0-9]+}} offen
+
+; CHECK: image_sample
+; CHECK: s_and_b64 exec, exec, [[LIVE]]
+; CHECK: buffer_store_dwordx4
+define amdgpu_ps void @test_alloca(float %data, i32 %a, i32 %idx) nounwind {
+entry:
+ %array = alloca [32 x i32], align 4
+
+ call void @llvm.amdgcn.buffer.store.f32(float %data, <4 x i32> undef, i32 0, i32 0, i1 0, i1 0)
+
+ %s.gep = getelementptr [32 x i32], [32 x i32]* %array, i32 0, i32 0
+ store volatile i32 %a, i32* %s.gep, align 4
+
+ call void @llvm.amdgcn.buffer.store.f32(float %data, <4 x i32> undef, i32 1, i32 0, i1 0, i1 0)
+
+ %c.gep = getelementptr [32 x i32], [32 x i32]* %array, i32 0, i32 %idx
+ %c = load i32, i32* %c.gep, align 4
+
+ %t = call <4 x float> @llvm.SI.image.sample.i32(i32 %c, <8 x i32> undef, <4 x i32> undef, i32 15, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0)
+
+ call void @llvm.amdgcn.buffer.store.v4f32(<4 x float> %t, <4 x i32> undef, i32 0, i32 0, i1 0, i1 0)
+
+ ret void
+}
+
+
declare void @llvm.amdgcn.image.store.v4i32(<4 x float>, <4 x i32>, <8 x i32>, i32, i1, i1, i1, i1) #1
+declare void @llvm.amdgcn.buffer.store.f32(float, <4 x i32>, i32, i32, i1, i1) #1
+declare void @llvm.amdgcn.buffer.store.v4f32(<4 x float>, <4 x i32>, i32, i32, i1, i1) #1
declare <4 x float> @llvm.amdgcn.image.load.v4i32(<4 x i32>, <8 x i32>, i32, i1, i1, i1, i1) #2
+declare float @llvm.amdgcn.buffer.load.f32(<4 x i32>, i32, i32, i1, i1) #2
declare <4 x float> @llvm.SI.image.sample.i32(i32, <8 x i32>, <4 x i32>, i32, i32, i32, i32, i32, i32, i32, i32) #3
declare <4 x float> @llvm.SI.image.sample.v4i32(<4 x i32>, <8 x i32>, <4 x i32>, i32, i32, i32, i32, i32, i32, i32, i32) #3