[llvm] [DirectX][SPIR-V] Fix `copysign` backend lowering (PR #217421)
Deric C. via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 19 17:18:52 PDT 2026
================
@@ -1055,6 +1056,31 @@ static Value *expandSignIntrinsic(CallInst *Orig) {
return Builder.CreateSub(ZextGT, ZextLT);
}
+// Expand llvm.copysign by combining the sign bit with the magnitude bits using
+// bitwise operations.
+static Value *expandCopySignIntrinsic(CallInst *Orig) {
+ Value *Magnitude = Orig->getOperand(0);
+ Value *Sign = Orig->getOperand(1);
+ Type *Ty = Orig->getType();
+
+ IRBuilder<> Builder(Orig);
+
+ unsigned BitWidth = 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);
+
+ Value *MagnitudeInt = Builder.CreateBitCast(Magnitude, IntTy);
+ Value *SignInt = Builder.CreateBitCast(Sign, IntTy);
----------------
Icohedron wrote:
The `bitcast half <-> i16` is rejected by the DXIL validator unless the module is in native 16-bit mode.
This isn't an issue with Clang today because a `half` without `-enable-16-bit-types` is just a float.
However, if we ever support the `min16float` type then this will be a validation error with a shader like: https://hlsl.godbolt.org/z/1ns1YPdY4
Suggestion: when the scalar type is 16-bit and native low precision is off, promote to f32 (`fpext` -> 32-bit bit trick -> `fptrunc`), or just bail out with a diagnostic.
https://github.com/llvm/llvm-project/pull/217421
More information about the llvm-commits
mailing list