ctx->v3f32 = LLVMVectorType(ctx->f32, 3);
ctx->v4f32 = LLVMVectorType(ctx->f32, 4);
ctx->v8i32 = LLVMVectorType(ctx->i32, 8);
+ ctx->iN_wavemask = LLVMIntTypeInContext(ctx->context, ctx->wave_size);
ctx->i8_0 = LLVMConstInt(ctx->i8, 0, false);
ctx->i8_1 = LLVMConstInt(ctx->i8, 1, false);
ac_build_ballot(struct ac_llvm_context *ctx,
LLVMValueRef value)
{
- const char *name = HAVE_LLVM >= 0x900 ? "llvm.amdgcn.icmp.i64.i32" : "llvm.amdgcn.icmp.i32";
+ const char *name;
+
+ if (HAVE_LLVM >= 0x900) {
+ if (ctx->wave_size == 64)
+ name = "llvm.amdgcn.icmp.i64.i32";
+ else
+ name = "llvm.amdgcn.icmp.i32.i32";
+ } else {
+ name = "llvm.amdgcn.icmp.i32";
+ }
LLVMValueRef args[3] = {
value,
ctx->i32_0,
args[0] = ac_to_integer(ctx, args[0]);
- return ac_build_intrinsic(ctx, name,
- ctx->i64, args, 3,
+ return ac_build_intrinsic(ctx, name, ctx->iN_wavemask, args, 3,
AC_FUNC_ATTR_NOUNWIND |
AC_FUNC_ATTR_READNONE |
AC_FUNC_ATTR_CONVERGENT);
{
LLVMValueRef vote_set = ac_build_ballot(ctx, value);
return LLVMBuildICmp(ctx->builder, LLVMIntNE, vote_set,
- LLVMConstInt(ctx->i64, 0, 0), "");
+ LLVMConstInt(ctx->iN_wavemask, 0, 0), "");
}
LLVMValueRef
vote_set, active_set, "");
LLVMValueRef none = LLVMBuildICmp(ctx->builder, LLVMIntEQ,
vote_set,
- LLVMConstInt(ctx->i64, 0, 0), "");
+ LLVMConstInt(ctx->iN_wavemask, 0, 0), "");
return LLVMBuildOr(ctx->builder, all, none, "");
}
LLVMValueRef
ac_build_mbcnt(struct ac_llvm_context *ctx, LLVMValueRef mask)
{
+ if (ctx->wave_size == 32) {
+ return ac_build_intrinsic(ctx, "llvm.amdgcn.mbcnt.lo", ctx->i32,
+ (LLVMValueRef []) { mask, ctx->i32_0 },
+ 2, AC_FUNC_ATTR_READNONE);
+ }
LLVMValueRef mask_vec = LLVMBuildBitCast(ctx->builder, mask,
LLVMVectorType(ctx->i32, 2),
"");
case TGSI_SEMANTIC_SUBGROUP_EQ_MASK:
{
LLVMValueRef id = ac_get_thread_id(&ctx->ac);
- id = LLVMBuildZExt(ctx->ac.builder, id, ctx->i64, "");
- value = LLVMBuildShl(ctx->ac.builder, LLVMConstInt(ctx->i64, 1, 0), id, "");
+ if (ctx->ac.wave_size == 64)
+ id = LLVMBuildZExt(ctx->ac.builder, id, ctx->i64, "");
+ value = LLVMBuildShl(ctx->ac.builder,
+ LLVMConstInt(ctx->ac.iN_wavemask, 1, 0), id, "");
+ if (ctx->ac.wave_size == 32)
+ value = LLVMBuildZExt(ctx->ac.builder, value, ctx->i64, "");
value = LLVMBuildBitCast(ctx->ac.builder, value, ctx->v2i32, "");
break;
}
if (decl->Semantic.Name == TGSI_SEMANTIC_SUBGROUP_GT_MASK ||
decl->Semantic.Name == TGSI_SEMANTIC_SUBGROUP_LE_MASK) {
/* All bits set except LSB */
- value = LLVMConstInt(ctx->i64, -2, 0);
+ value = LLVMConstInt(ctx->ac.iN_wavemask, -2, 0);
} else {
/* All bits set */
- value = LLVMConstInt(ctx->i64, -1, 0);
+ value = LLVMConstInt(ctx->ac.iN_wavemask, -1, 0);
}
- id = LLVMBuildZExt(ctx->ac.builder, id, ctx->i64, "");
+ if (ctx->ac.wave_size == 64)
+ id = LLVMBuildZExt(ctx->ac.builder, id, ctx->i64, "");
value = LLVMBuildShl(ctx->ac.builder, value, id, "");
if (decl->Semantic.Name == TGSI_SEMANTIC_SUBGROUP_LE_MASK ||
decl->Semantic.Name == TGSI_SEMANTIC_SUBGROUP_LT_MASK)
value = LLVMBuildNot(ctx->ac.builder, value, "");
+ if (ctx->ac.wave_size == 32)
+ value = LLVMBuildZExt(ctx->ac.builder, value, ctx->i64, "");
value = LLVMBuildBitCast(ctx->ac.builder, value, ctx->v2i32, "");
break;
}
tmp = lp_build_emit_fetch(bld_base, emit_data->inst, 0, TGSI_CHAN_X);
tmp = ac_build_ballot(&ctx->ac, tmp);
- tmp = LLVMBuildBitCast(builder, tmp, ctx->v2i32, "");
- emit_data->output[0] = LLVMBuildExtractElement(builder, tmp, ctx->i32_0, "");
- emit_data->output[1] = LLVMBuildExtractElement(builder, tmp, ctx->i32_1, "");
+ emit_data->output[0] = LLVMBuildTrunc(builder, tmp, ctx->i32, "");
+
+ if (ctx->ac.wave_size == 32) {
+ emit_data->output[1] = ctx->i32_0;
+ } else {
+ tmp = LLVMBuildLShr(builder, tmp, LLVMConstInt(ctx->i64, 32, 0), "");
+ emit_data->output[1] = LLVMBuildTrunc(builder, tmp, ctx->i32, "");
+ }
}
static void read_lane_emit(