[llvm] [DirectX][SPIR-V] Fix `copysign` backend lowering (PR #217421)

Farzon Lotfi via llvm-commits llvm-commits at lists.llvm.org
Mon Aug 24 12:05:19 PDT 2026


================
@@ -1065,20 +1065,41 @@ static Value *expandCopySignIntrinsic(CallInst *Orig) {
 
   IRBuilder<> Builder(Orig);
 
-  unsigned BitWidth = Ty->getScalarSizeInBits();
+  bool IsDouble = Ty->getScalarType()->isDoubleTy();
+  unsigned BitWidth = IsDouble ? 32 : Ty->getScalarSizeInBits();
   Type *IntTy = Ty->getWithNewType(Builder.getIntNTy(BitWidth));
 
-  // `ConstantInt::get` broadcasts to a splat when `IntTy` is a vector.
-  APInt SignMaskVal = APInt::getSignMask(BitWidth);
-  Constant *SignMask = ConstantInt::get(IntTy, SignMaskVal);
-  Constant *NotSignMask = ConstantInt::get(IntTy, ~SignMaskVal);
+  auto CopySignBit = [&](Value *MagnitudeInt, Value *SignInt) {
+    APInt SignMaskVal = APInt::getSignMask(BitWidth);
+    // `ConstantInt::get` broadcasts to a splat when `IntTy` is a vector.
+    Constant *SignMask = ConstantInt::get(IntTy, SignMaskVal);
+    Constant *NotSignMask = ConstantInt::get(IntTy, ~SignMaskVal);
+
+    Value *MagnitudeBits = Builder.CreateAnd(MagnitudeInt, NotSignMask);
+    Value *SignBits = Builder.CreateAnd(SignInt, SignMask);
+    return Builder.CreateOr(MagnitudeBits, SignBits);
+  };
+
+  // Avoid i64 bitwise ops, which require the Int64Ops shader feature.
+  if (IsDouble) {
----------------
farzonl wrote:

Fair we can move forward with this PR, but I think we may want to change some pass ordering to make this possible in the future so a follow on issue would be nice here. I believe the metadata I want to check is set by DXILShaderFlags. Maybe we should be having a broader discussion about moving DXILShaderFlags earlier in the backend pipeline. or intrinsic expansion later.

https://github.com/llvm/llvm-project/pull/217421


More information about the llvm-commits mailing list