Skip to content

Commit 368da36

Browse files
authored
[SPIR-V]: Fix spirv codegen for uabs intrinsic when argument is unsigned. (microsoft#7750)
Fix the spirv codegen for `abs()` on `uint`, to **not** generate `OpExtInst` instruction but simply load and pass the value. Fixes microsoft#7512 # Example ``` [numthreads(1,1,1)] void main() { uint32_t A = uint32_t(0xffffffff); uint32_t B = abs(A); } ``` ## Previously generated SPIR-V ``` %A = OpVariable %_ptr_Function_uint Function %B = OpVariable %_ptr_Function_uint Function OpStore %A %uint_4294967295 %13 = OpLoad %uint %A %14 = OpExtInst %int %1 SAbs %13 OpStore %B %14 ``` ## Fix ``` %A = OpVariable %_ptr_Function_uint Function %B = OpVariable %_ptr_Function_uint Function OpStore %A %uint_4294967295 %13 = OpLoad %uint %A OpStore %B %13 ``` which is equivalent to ``` [numthreads(1,1,1)] void main() { uint32_t A = uint32_t(0xffffffff); uint32_t B = A; } ```
1 parent 7670b16 commit 368da36

2 files changed

Lines changed: 23 additions & 1 deletion

File tree

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9685,6 +9685,17 @@ SpirvEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
96859685
callExpr->getExprLoc(),
96869686
callExpr->getSourceRange());
96879687
break;
9688+
}
9689+
case hlsl::IntrinsicOp::IOP_uabs: {
9690+
if (isUintOrVecMatOfUintType(callExpr->getArg(0)->getType())) {
9691+
// If unsigned, it's a no-op. Skip generating an `OpExtInst` instruction.
9692+
// Simply load and store the value.
9693+
auto *loadInst = doExpr(callExpr->getArg(0));
9694+
retVal = loadInst;
9695+
break;
9696+
}
9697+
emitError("uabs intrinsic requires unsigned integer input type", srcLoc);
9698+
return nullptr;
96889699
}
96899700
INTRINSIC_SPIRV_OP_CASE(countbits, BitCount, false);
96909701
INTRINSIC_SPIRV_OP_CASE(fmod, FRem, true);
@@ -9693,7 +9704,6 @@ SpirvEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
96939704
INTRINSIC_SPIRV_OP_CASE(and, LogicalAnd, false);
96949705
INTRINSIC_SPIRV_OP_CASE(or, LogicalOr, false);
96959706
INTRINSIC_OP_CASE(round, RoundEven, true);
9696-
INTRINSIC_OP_CASE(uabs, SAbs, true);
96979707
INTRINSIC_OP_CASE_INT_FLOAT(abs, SAbs, FAbs, true);
96989708
INTRINSIC_OP_CASE(acos, Acos, true);
96999709
INTRINSIC_OP_CASE(asin, Asin, true);

tools/clang/test/CodeGenSPIRV/intrinsics.abs.hlsl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@ void main() {
6464
int3 i;
6565
iresult3 = abs(i);
6666

67+
// abs on unsigned int is a no-op.
68+
// CHECK-NEXT: [[j:%[0-9]+]] = OpLoad %uint %j
69+
// CHECK-NEXT: OpStore %j [[j]]
70+
uint j;
71+
j = abs(j);
72+
73+
// abs on unsigned int vector is a no-op.
74+
// CHECK-NEXT: [[k:%[0-9]+]] = OpLoad %v3uint %k
75+
// CHECK-NEXT: OpStore %k [[k]]
76+
uint3 k;
77+
k = abs(k);
78+
6779
// TODO: Integer matrices are not supported yet. Therefore we cannot run the following test yet.
6880
// XXXXX-NEXT: [[h:%[0-9]+]] = OpLoad %mat3v4float %h
6981
// XXXXX-NEXT: [[h_row0:%[0-9]+]] = OpCompositeExtract %v4float [[h]] 0

0 commit comments

Comments
 (0)