[clang] [llvm] [HLSL][DXIL] InterlockedOr and InterlockedOr64 builtins (PR #180804)
Alexander Johnston via cfe-commits
cfe-commits at lists.llvm.org
Thu Apr 9 09:48:48 PDT 2026
================
@@ -301,6 +300,98 @@ static Value *handleElementwiseF32ToF16(CodeGenFunction &CGF,
llvm_unreachable("Intrinsic F32ToF16 not supported by target architecture");
}
+static Value *handleInterlockedOr(CodeGenFunction &CGF, const CallExpr *E,
+ const bool HasReturn) {
+ const bool Is32Bit = CGF.getContext().getTypeSize(
+ E->getArg(E->getNumArgs() - 1)->getType()) == 32;
+ Value *HandleOp = CGF.EmitScalarExpr(E->getArg(0));
+ Value *IndexOp = CGF.EmitScalarExpr(E->getArg(1));
+ Value *StructuredBufIndexOp;
+ Value *NewValueOp;
+ Value *OldValueOp;
+ unsigned OldValueArgIdx;
+ if (E->getNumArgs() == 3) {
+ // (handle, index, newValue)
+ NewValueOp = CGF.EmitScalarExpr(E->getArg(2));
+ } else if (E->getNumArgs() == 4) {
+ if (HasReturn) {
+ // (handle, index, newValue, oldValue)
+ NewValueOp = CGF.EmitScalarExpr(E->getArg(2));
+ OldValueArgIdx = 3;
+ } else {
+ // (handle, index, index, newValue)
----------------
Alexander-Johnston wrote:
I have this case for handling the two indexes generated from doing something like `InterlockedOr(buf[1].z, 0);`, where the index into the buffer is the first index and the index into the struct is the second.
We can't currently generate the freestanding `InterlockedX(buffer[index]...)` yet because of the current buffer implementation resolving too quickly, stripping away the buffer and index information. But this does the initial work of allowing us to implement those functions in the style of
```
InterlockedX(RWStructuredBuffer[index].index2, val) {
__builtin_hlsl_interlocked_X(buffer, index, index2, val);
}
```
While I'm sure it'll be clearer in the larger picture once the rest of the implementation is here, I'll try to make it a bit clearer in isolation too.
https://github.com/llvm/llvm-project/pull/180804
More information about the cfe-commits
mailing list