================
@@ -300,6 +300,122 @@ static Value *handleElementwiseF32ToF16(CodeGenFunction 
&CGF,
   llvm_unreachable("Intrinsic F32ToF16 not supported by target architecture");
 }
 
+// Not sure where would be best for this to live
+// AtomicBinOp uses an i32 to determine the operation mode as follows
+enum AtomicOperationCode : uint {
+  Add = 0,
+  And = 1,
+  Or = 2,
+  Xor = 3,
+  IMin = 4,
+  IMax = 5,
+  UMin = 6,
+  UMax = 7,
+  Exchange = 8
+};
+
+static Value *handleAtomicBinOp(CodeGenFunction &CGF, const CallExpr *E,
+                                const AtomicOperationCode OpCode,
+                                const bool HasReturn, const bool Is32Bit) {
+  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)
+      StructuredBufIndexOp = CGF.EmitScalarExpr(E->getArg(2));
+      NewValueOp = CGF.EmitScalarExpr(E->getArg(3));
+    }
+  } else {
+    // (handle, index, index, newValue, oldValue)
+    StructuredBufIndexOp = CGF.EmitScalarExpr(E->getArg(2));
+    NewValueOp = CGF.EmitScalarExpr(E->getArg(3));
+    OldValueArgIdx = 4;
+  }
+
+  switch (CGF.CGM.getTarget().getTriple().getArch()) {
+  case llvm::Triple::dxil: {
+    QualType HandleTy = E->getArg(0)->getType();
+    const HLSLAttributedResourceType *ResourceTy =
+        HandleTy->getAs<HLSLAttributedResourceType>();
+
+    // AtomicBinOp uses an i32 to determine the operation mode as follows
+    // Add: 0, And: 1, Or: 2, Xor: 3, IMin: 4, IMax: 5, UMin: 6, UMax: 7,
+    // Exchange: 8
+    Value *ModeConstant = ConstantInt::get(CGF.Int32Ty, OpCode);
+
+    // AtomicBinOp has 3 coordinate params which must be handled differently
+    // depending on the resource type being accessed.
+    // Initially undef all the coordinates then fill as required
+    Value *Undef = UndefValue::get(CGF.Int32Ty);
+    Value *C0 = Undef;
+    Value *C1 = Undef;
+    Value *C2 = Undef;
----------------
Alexander-Johnston wrote:

I've replaced these with Poison to try and downgrade them in the backend as you 
suggest.
Maybe I'm looking in the wrong places, but I don't see a specific downgrader 
anywhere in the DirectX backend. I noticed some manual downgrading in 
DXILOpLowering on some resource intrinsics, but this path is already covered 
for the interlocked/atomicBinOp by the `let intrinsics...` in DXIL.td. What do 
you suggest?

https://github.com/llvm/llvm-project/pull/180804
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to