[llvm] [DirectX] Add lowering support for `llvm.fsh[l|r].*` (PR #170570)
Deric C. via llvm-commits
llvm-commits at lists.llvm.org
Mon Dec 8 11:54:38 PST 2025
================
@@ -656,6 +659,32 @@ static Value *expandAtan2Intrinsic(CallInst *Orig) {
return Result;
}
+template <bool LeftFunnel>
+static Value *expandFunnelShiftIntrinsic(CallInst *Orig) {
+ Type *Ty = Orig->getType();
+ Value *A = Orig->getOperand(0);
+ Value *B = Orig->getOperand(1);
+ Value *Shift = Orig->getOperand(2);
+
+ IRBuilder<> Builder(Orig);
+
+ unsigned BitWidth = Ty->getScalarSizeInBits();
+ Constant *Mask = ConstantInt::get(Ty, BitWidth - 1);
+ Constant *Size = ConstantInt::get(Ty, BitWidth);
+
+ // The shift is not required to be masked as DXIL op will do so automatically
+ Value *Left =
+ LeftFunnel ? Builder.CreateShl(A, Shift) : Builder.CreateLShr(B, Shift);
+
+ Value *MaskedShift = Builder.CreateAnd(Shift, Mask);
+ Value *InverseShift = Builder.CreateSub(Size, MaskedShift);
+ Value *Right = LeftFunnel ? Builder.CreateLShr(B, InverseShift)
+ : Builder.CreateShl(A, InverseShift);
----------------
Icohedron wrote:
Shouldn't there be an edge-case for when the shift operand is 0 or N (where N is the number of bits)?
Consider 0 for example:
If `Shift == 0` then `InverseShift = N - (Shift mod N) = N`, but `shl` and `[l|a]shr` in LLVM [returns poison](https://llvm.org/docs/LangRef.html#shl-instruction) if the number of bits to shift by is equal to or greater than the number of bits in its operand (N).
In LLVM 3.7, [the result is undefined instead of returning poison](https://releases.llvm.org/3.7.0/docs/LangRef.html#shl-instruction) when the number of bits to shift by is >= N.
If the result is not undefined or poison in DXIL and I assume that DXIL will mask/modulo the shift amount for `shl` and `[l|a]shr`, then `InverseShift = N mod N = 0` and then the result becomes `(A << 0) | (B >> 0) == A | B` or `(A >> 0) | (B << 0) == A | B` when the result should just be `A`.
https://github.com/llvm/llvm-project/pull/170570
More information about the llvm-commits
mailing list