gallivm: Introduce lp_format_intrinsic.

For adding .v4f32 like suffixes to intrinsics, taking special care for
scalar case, which was being often neglected.

This fixes invalid IR when doing mipmap filtering on SSE2 (the only
case where we'd use intrinsics with scalars.)

Reviewed-by: Roland Scheidegger <sroland@vmware.com>
This commit is contained in:
Jose Fonseca 2016-04-03 22:52:53 +01:00
parent 7af12a8dc6
commit 7ad49daca6
3 changed files with 54 additions and 14 deletions

View File

@ -1493,7 +1493,7 @@ lp_build_abs(struct lp_build_context *bld,
if(type.floating) {
char intrinsic[32];
util_snprintf(intrinsic, sizeof intrinsic, "llvm.fabs.v%uf%u", type.length, type.width);
lp_format_intrinsic(intrinsic, sizeof intrinsic, "llvm.fabs", vec_type);
return lp_build_intrinsic_unary(builder, intrinsic, vec_type, a);
}
@ -1880,9 +1880,7 @@ lp_build_round_arch(struct lp_build_context *bld,
break;
}
util_snprintf(intrinsic, sizeof intrinsic, "%s.v%uf%u",
intrinsic_root, type.length, type.width);
lp_format_intrinsic(intrinsic, sizeof intrinsic, intrinsic_root, bld->vec_type);
return lp_build_intrinsic_unary(builder, intrinsic, bld->vec_type, a);
}
else /* (util_cpu_caps.has_altivec) */
@ -2026,7 +2024,7 @@ lp_build_floor(struct lp_build_context *bld,
if (type.width != 32) {
char intrinsic[32];
util_snprintf(intrinsic, sizeof intrinsic, "llvm.floor.v%uf%u", type.length, type.width);
lp_format_intrinsic(intrinsic, sizeof intrinsic, "llvm.floor", vec_type);
return lp_build_intrinsic_unary(builder, intrinsic, vec_type, a);
}
@ -2101,7 +2099,7 @@ lp_build_ceil(struct lp_build_context *bld,
if (type.width != 32) {
char intrinsic[32];
util_snprintf(intrinsic, sizeof intrinsic, "llvm.ceil.v%uf%u", type.length, type.width);
lp_format_intrinsic(intrinsic, sizeof intrinsic, "llvm.ceil", vec_type);
return lp_build_intrinsic_unary(builder, intrinsic, vec_type, a);
}
@ -2438,15 +2436,8 @@ lp_build_sqrt(struct lp_build_context *bld,
assert(lp_check_value(type, a));
/* TODO: optimize the constant case */
assert(type.floating);
if (type.length == 1) {
util_snprintf(intrinsic, sizeof intrinsic, "llvm.sqrt.f%u", type.width);
}
else {
util_snprintf(intrinsic, sizeof intrinsic, "llvm.sqrt.v%uf%u", type.length, type.width);
}
lp_format_intrinsic(intrinsic, sizeof intrinsic, "llvm.sqrt", vec_type);
return lp_build_intrinsic_unary(builder, intrinsic, vec_type, a);
}

View File

@ -45,6 +45,7 @@
#include "util/u_debug.h"
#include "util/u_string.h"
#include "lp_bld_const.h"
#include "lp_bld_intr.h"
@ -52,6 +53,48 @@
#include "lp_bld_pack.h"
void
lp_format_intrinsic(char *name,
size_t size,
const char *name_root,
LLVMTypeRef type)
{
unsigned length = 0;
unsigned width;
char c;
LLVMTypeKind kind = LLVMGetTypeKind(type);
if (kind == LLVMVectorTypeKind) {
length = LLVMGetVectorSize(type);
type = LLVMGetElementType(type);
kind = LLVMGetTypeKind(type);
}
switch (kind) {
case LLVMIntegerTypeKind:
c = 'i';
width = LLVMGetIntTypeWidth(type);
break;
case LLVMFloatTypeKind:
c = 'f';
width = 32;
break;
case LLVMDoubleTypeKind:
c = 'f';
width = 64;
break;
default:
assert(0);
}
if (length) {
util_snprintf(name, size, "%s.v%u%c%u", name_root, length, c, width);
} else {
util_snprintf(name, size, "%s.%c%u", name_root, c, width);
}
}
LLVMValueRef
lp_declare_intrinsic(LLVMModuleRef module,
const char *name,

View File

@ -47,6 +47,12 @@
#define LP_MAX_FUNC_ARGS 32
void
lp_format_intrinsic(char *name,
size_t size,
const char *name_root,
LLVMTypeRef type);
LLVMValueRef
lp_declare_intrinsic(LLVMModuleRef module,
const char *name,