================
@@ -833,24 +833,42 @@ void 
HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() {
   }
 }
 
+// Shapes of the synthesized atomic overloads. The read-modify-write operations
+// can report the previous value through a trailing reference. Every argument
+// of compare-store is an input.
+enum class AtomicOverloadShape {
+  Binary,             // (dest, value)
+  BinaryWithOriginal, // (dest, value, original_value)
+  CompareStore,       // (dest, compare_value, value)
+};
+
 // Build a single overload of an HLSL atomic intrinsic in the hlsl namespace.
 // `dest` is an address-space-qualified reference; `original_value` (when
 // present) is a plain reference. The synthesized FunctionDecl aliases the
 // underlying clang builtin via BuiltinAliasAttr.
 static void buildAtomicOverload(Sema &S, NamespaceDecl *NS, StringRef FuncName,
                                 StringRef BuiltinName, QualType ElemTy,
-                                LangAS DestAS, bool ThreeArg) {
+                                LangAS DestAS, AtomicOverloadShape Shape) {
   ASTContext &AST = S.getASTContext();
 
   QualType DestTy =
       AST.getLValueReferenceType(AST.getAddrSpaceQualType(ElemTy, DestAS));
   QualType OrigRefTy = AST.getLValueReferenceType(ElemTy);
 
-  SmallVector<QualType, 3> ParamTypes;
-  ParamTypes.push_back(DestTy);
-  ParamTypes.push_back(ElemTy);
-  if (ThreeArg)
+  SmallVector<QualType, 3> ParamTypes = {DestTy, ElemTy};
+  if (Shape == AtomicOverloadShape::BinaryWithOriginal)
     ParamTypes.push_back(OrigRefTy);
+  else if (Shape == AtomicOverloadShape::CompareStore)
+    ParamTypes.push_back(ElemTy);
----------------
bob80905 wrote:

When checking against DXC, it looks like it automatically casts into uint. Your 
DXC example is probably in range of 0 - uint max.
Do you get the same thing if you try RWStructedBuffer<uint> ?
If you gave DXC something larger than uintmax, then it should emit `undef`.
DXC converts the operands to uint, where 2147483648 and 4294967040 are both in 
range, so it folds them to the bit patterns -2147483648 and -256. Clang 
converts to the destination element type `int`, where the same literals are out 
of range, so it warns and emits poison.

Give DXC a genuinely out-of-range value for uint, and it should emit undef, the 
old-LLVM equivalent of poison.
I think we want to keep the current behavior because if the buffer is of type 
int, then DXC emits undef, while clang emits -5.0f correctly as -5u.

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

Reply via email to