summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,