summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>2020-02-26 15:04:38 +0100
committerEric Engestrom <eric@engestrom.ch>2020-03-06 22:59:23 +0100
commitd0bfb09c6789f1e3e1f736f884d743a7fcc59bfc (patch)
tree562258501930e0d0d9841a05810980bfd775057f
parente32110df115d6b371bc0488def1950493684379e (diff)
ac/llvm: fix 64-bit fmed3
Lower 64-bit fmed3 because LLVM doesn't expose an intrinsic. Fixes dEQP-VK.spirv_assembly.instruction.amd_trinary_minmax.mid3.f64.*. Fixes: d6a07732c9c ("ac: use llvm.amdgcn.fmed3 intrinsic for nir_op_fmed3") Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/3962> (cherry picked from commit 50b8c2527464dbe18a01ab6412de4465cebf2225)
-rw-r--r--.pick_status.json2
-rw-r--r--src/amd/llvm/ac_llvm_build.c48
2 files changed, 32 insertions, 18 deletions
diff --git a/.pick_status.json b/.pick_status.json
index 48f2f9e2cac..2ab7391d93d 100644
--- a/.pick_status.json
+++ b/.pick_status.json
@@ -3280,7 +3280,7 @@
"description": "ac/llvm: fix 64-bit fmed3",
"nominated": true,
"nomination_type": 1,
- "resolution": 0,
+ "resolution": 1,
"master_sha": null,
"because_sha": "d6a07732c9c155c73f7d2cddc10faa7eab768df9"
},
diff --git a/src/amd/llvm/ac_llvm_build.c b/src/amd/llvm/ac_llvm_build.c
index 1330d254de2..36eb1e316a5 100644
--- a/src/amd/llvm/ac_llvm_build.c
+++ b/src/amd/llvm/ac_llvm_build.c
@@ -2698,27 +2698,41 @@ LLVMValueRef ac_build_fmed3(struct ac_llvm_context *ctx, LLVMValueRef src0,
LLVMValueRef src1, LLVMValueRef src2,
unsigned bitsize)
{
- LLVMTypeRef type;
- char *intr;
+ LLVMValueRef result;
- if (bitsize == 16) {
- intr = "llvm.amdgcn.fmed3.f16";
- type = ctx->f16;
- } else if (bitsize == 32) {
- intr = "llvm.amdgcn.fmed3.f32";
- type = ctx->f32;
+ if (bitsize == 64) {
+ /* Lower 64-bit fmed because LLVM doesn't expose an intrinsic. */
+ LLVMValueRef min1, min2, max1;
+
+ min1 = ac_build_fmin(ctx, src0, src1);
+ max1 = ac_build_fmax(ctx, src0, src1);
+ min2 = ac_build_fmin(ctx, max1, src2);
+
+ result = ac_build_fmax(ctx, min2, min1);
} else {
- intr = "llvm.amdgcn.fmed3.f64";
- type = ctx->f64;
+ LLVMTypeRef type;
+ char *intr;
+
+ if (bitsize == 16) {
+ intr = "llvm.amdgcn.fmed3.f16";
+ type = ctx->f16;
+ } else {
+ assert(bitsize == 32);
+ intr = "llvm.amdgcn.fmed3.f32";
+ type = ctx->f32;
+ }
+
+ LLVMValueRef params[] = {
+ src0,
+ src1,
+ src2,
+ };
+
+ result = ac_build_intrinsic(ctx, intr, type, params, 3,
+ AC_FUNC_ATTR_READNONE);
}
- LLVMValueRef params[] = {
- src0,
- src1,
- src2,
- };
- return ac_build_intrinsic(ctx, intr, type, params, 3,
- AC_FUNC_ATTR_READNONE);
+ return result;
}
LLVMValueRef ac_build_fract(struct ac_llvm_context *ctx, LLVMValueRef src0,