Skip to content

Commit 47c642f

Browse files
committed
[DAGCombiner] Fold IEEE fmul/fdiv by Pow2 to add/sub of exp
Note: This is moving D154678 which previously implemented this in InstCombine. Concerns where brought up that this was de-canonicalizing and really targeting a codegen improvement, so placing in DAGCombiner. This implements: ``` (fmul C, (uitofp Pow2)) -> (bitcast_to_FP (add (bitcast_to_INT C), Log2(Pow2) << mantissa)) (fdiv C, (uitofp Pow2)) -> (bitcast_to_FP (sub (bitcast_to_INT C), Log2(Pow2) << mantissa)) ``` The motivation is mostly fdiv where 2^(-p) is a fairly common expression. The patch is intentionally conservative about the transform, only doing so if we: 1) have IEEE floats 2) C is normal 3) add/sub of max(Log2(Pow2)) stays in the min/max exponent bounds. Alive2 can't realistically prove this, but did test float16/float32 cases (within the bounds of the above rules) exhaustively. Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D154805
1 parent 32a4691 commit 47c642f

File tree

6 files changed

+649
-1972
lines changed

6 files changed

+649
-1972
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,24 @@ class TargetLoweringBase {
810810
return !XC;
811811
}
812812

813+
// Return true if its desirable to perform the following transform:
814+
// (fmul C, (uitofp Pow2))
815+
// -> (bitcast_to_FP (add (bitcast_to_INT C), Log2(Pow2) << mantissa))
816+
// (fdiv C, (uitofp Pow2))
817+
// -> (bitcast_to_FP (sub (bitcast_to_INT C), Log2(Pow2) << mantissa))
818+
//
819+
// This is only queried after we have verified the transform will be bitwise
820+
// equals.
821+
//
822+
// SDNode *N : The FDiv/FMul node we want to transform.
823+
// SDValue FPConst: The Float constant operand in `N`.
824+
// SDValue IntPow2: The Integer power of 2 operand in `N`.
825+
virtual bool optimizeFMulOrFDivAsShiftAddBitcast(SDNode *N, SDValue FPConst,
826+
SDValue IntPow2) const {
827+
// Default to avoiding fdiv which is often very expensive.
828+
return N->getOpcode() == ISD::FDIV;
829+
}
830+
813831
/// These two forms are equivalent:
814832
/// sub %y, (xor %x, -1)
815833
/// add (add %x, 1), %y

0 commit comments

Comments
 (0)