return ac_build_intrinsic(ctx, name, result_type, params, 1, AC_FUNC_ATTR_READNONE);
}
+static LLVMValueRef emit_intrin_1f_param_scalar(struct ac_llvm_context *ctx,
+ const char *intrin,
+ LLVMTypeRef result_type,
+ LLVMValueRef src0)
+{
+ if (LLVMGetTypeKind(result_type) != LLVMVectorTypeKind)
+ return emit_intrin_1f_param(ctx, intrin, result_type, src0);
+
+ LLVMTypeRef elem_type = LLVMGetElementType(result_type);
+ LLVMValueRef ret = LLVMGetUndef(result_type);
+
+ /* Scalarize the intrinsic, because vectors are not supported. */
+ for (unsigned i = 0; i < LLVMGetVectorSize(result_type); i++) {
+ char name[64], type[64];
+ LLVMValueRef params[] = {
+ ac_to_float(ctx, ac_llvm_extract_elem(ctx, src0, i)),
+ };
+
+ ac_build_type_name_for_intr(LLVMTypeOf(params[0]), type, sizeof(type));
+ ASSERTED const int length = snprintf(name, sizeof(name), "%s.%s", intrin, type);
+ assert(length < sizeof(name));
+ ret = LLVMBuildInsertElement(ctx->builder, ret,
+ ac_build_intrinsic(ctx, name, elem_type, params,
+ 1, AC_FUNC_ATTR_READNONE),
+ LLVMConstInt(ctx->i32, i, 0), "");
+ }
+ return ret;
+}
+
static LLVMValueRef emit_intrin_2f_param(struct ac_llvm_context *ctx,
const char *intrin,
LLVMTypeRef result_type,
LLVMTypeRef src1_type = LLVMTypeOf(src1);
LLVMTypeRef src2_type = LLVMTypeOf(src2);
- assert(LLVMGetTypeKind(LLVMTypeOf(src0)) != LLVMVectorTypeKind);
-
if (LLVMGetTypeKind(src1_type) == LLVMPointerTypeKind &&
LLVMGetTypeKind(src2_type) != LLVMPointerTypeKind) {
src2 = LLVMBuildIntToPtr(ctx->builder, src2, src1_type, "");
}
LLVMValueRef v = LLVMBuildICmp(ctx->builder, LLVMIntNE, src0,
- ctx->i32_0, "");
+ LLVMConstNull(LLVMTypeOf(src0)), "");
return LLVMBuildSelect(ctx->builder, v,
ac_to_integer_or_pointer(ctx, src1),
ac_to_integer_or_pointer(ctx, src2), "");
unsigned num_components = instr->dest.dest.ssa.num_components;
unsigned src_components;
LLVMTypeRef def_type = get_def_type(ctx, &instr->dest.dest.ssa);
- bool saved_inexact = false;
-
- if (instr->exact)
- saved_inexact = ac_disable_inexact_math(ctx->ac.builder);
assert(nir_op_infos[instr->op].num_inputs <= ARRAY_SIZE(src));
switch (instr->op) {
case nir_op_umod:
result = LLVMBuildURem(ctx->ac.builder, src[0], src[1], "");
break;
- case nir_op_fmod:
- /* lower_fmod only lower 16-bit and 32-bit fmod */
- assert(instr->dest.dest.ssa.bit_size == 64);
- src[0] = ac_to_float(&ctx->ac, src[0]);
- src[1] = ac_to_float(&ctx->ac, src[1]);
- result = ac_build_fdiv(&ctx->ac, src[0], src[1]);
- result = emit_intrin_1f_param(&ctx->ac, "llvm.floor",
- ac_to_float_type(&ctx->ac, def_type), result);
- result = LLVMBuildFMul(ctx->ac.builder, src[1] , result, "");
- result = LLVMBuildFSub(ctx->ac.builder, src[0], result, "");
- break;
case nir_op_irem:
result = LLVMBuildSRem(ctx->ac.builder, src[0], src[1], "");
break;
result = LLVMBuildFDiv(ctx->ac.builder, ctx->ac.f64_1,
ac_to_float(&ctx->ac, src[0]), "");
} else {
- result = emit_intrin_1f_param(&ctx->ac, "llvm.amdgcn.rcp",
- ac_to_float_type(&ctx->ac, def_type), src[0]);
+ result = emit_intrin_1f_param_scalar(&ctx->ac, "llvm.amdgcn.rcp",
+ ac_to_float_type(&ctx->ac, def_type), src[0]);
}
if (ctx->abi->clamp_div_by_zero)
result = ac_build_fmin(&ctx->ac, result,
result = ac_build_umin(&ctx->ac, src[0], src[1]);
break;
case nir_op_isign:
- result = ac_build_isign(&ctx->ac, src[0],
- instr->dest.dest.ssa.bit_size);
+ result = ac_build_isign(&ctx->ac, src[0]);
break;
case nir_op_fsign:
src[0] = ac_to_float(&ctx->ac, src[0]);
- result = ac_build_fsign(&ctx->ac, src[0],
- instr->dest.dest.ssa.bit_size);
+ result = ac_build_fsign(&ctx->ac, src[0]);
break;
case nir_op_ffloor:
result = emit_intrin_1f_param(&ctx->ac, "llvm.floor",
ac_to_float_type(&ctx->ac, def_type),src[0]);
break;
case nir_op_ffract:
- src[0] = ac_to_float(&ctx->ac, src[0]);
- result = ac_build_fract(&ctx->ac, src[0],
- instr->dest.dest.ssa.bit_size);
+ result = emit_intrin_1f_param_scalar(&ctx->ac, "llvm.amdgcn.fract",
+ ac_to_float_type(&ctx->ac, def_type), src[0]);
break;
case nir_op_fsin:
result = emit_intrin_1f_param(&ctx->ac, "llvm.sin",
ac_to_float_type(&ctx->ac, def_type), src[0]);
break;
case nir_op_frsq:
- result = emit_intrin_1f_param(&ctx->ac, "llvm.amdgcn.rsq",
- ac_to_float_type(&ctx->ac, def_type), src[0]);
+ result = emit_intrin_1f_param_scalar(&ctx->ac, "llvm.amdgcn.rsq",
+ ac_to_float_type(&ctx->ac, def_type), src[0]);
if (ctx->abi->clamp_div_by_zero)
result = ac_build_fmin(&ctx->ac, result,
LLVMConstReal(ac_to_float_type(&ctx->ac, def_type), FLT_MAX));
result = ac_to_integer_or_pointer(&ctx->ac, result);
ctx->ssa_defs[instr->dest.dest.ssa.index] = result;
}
-
- if (instr->exact)
- ac_restore_inexact_math(ctx->ac.builder, saved_inexact);
}
static void visit_load_const(struct ac_nir_context *ctx,
break;
case nir_deref_type_ptr_as_array:
if (instr->mode == nir_var_mem_global) {
- unsigned stride = nir_deref_instr_ptr_as_array_stride(instr);
+ unsigned stride = nir_deref_instr_array_stride(instr);
LLVMValueRef index = get_src(ctx, instr->arr.index);
if (LLVMTypeOf(index) != ctx->ac.i64)
*/
indirect_mask |= nir_var_function_temp;
- progress |= nir_lower_indirect_derefs(nir, indirect_mask);
+ progress |= nir_lower_indirect_derefs(nir, indirect_mask, UINT32_MAX);
return progress;
}