mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-25 13:24:46 +00:00
Optimize vector fabs of bitcasted constant integer values.
Allow vector fabs operations on bitcasted constant integer values to be optimized in the same way that we already optimize scalar fabs. So for code like this: %bitcast = bitcast i64 18446744069414584320 to <2 x float> ; 0xFFFF_FFFF_0000_0000 %fabs = call <2 x float> @llvm.fabs.v2f32(<2 x float> %bitcast) %ret = bitcast <2 x float> %fabs to i64 Instead of generating something like this: movabsq (constant pool loadi of mask for sign bits) vmovq (move from integer register to vector/fp register) vandps (mask off sign bits) vmovq (move vector/fp register back to integer return register) We should generate: mov (put constant value in return register) I have also removed a redundant clause in the first 'if' statement: N0.getOperand(0).getValueType().isInteger() is the same thing as: IntVT.isInteger() Testcases for x86 and ARM added to existing files that deal with vector fabs. One existing testcase for x86 removed because it is no longer ideal. For more background, please see: http://reviews.llvm.org/D4770 And: http://llvm.org/bugs/show_bug.cgi?id=20354 Differential Revision: http://reviews.llvm.org/D4785 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@214892 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -7409,22 +7409,28 @@ SDValue DAGCombiner::visitFABS(SDNode *N) {
|
||||
if (N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FCOPYSIGN)
|
||||
return DAG.getNode(ISD::FABS, SDLoc(N), VT, N0.getOperand(0));
|
||||
|
||||
// Transform fabs(bitconvert(x)) -> bitconvert(x&~sign) to avoid loading
|
||||
// Transform fabs(bitconvert(x)) -> bitconvert(x & ~sign) to avoid loading
|
||||
// constant pool values.
|
||||
// TODO: We can also optimize for vectors here, but we need to make sure
|
||||
// that the sign mask is created properly for each vector element.
|
||||
if (!TLI.isFAbsFree(VT) &&
|
||||
N0.getOpcode() == ISD::BITCAST && N0.getNode()->hasOneUse() &&
|
||||
N0.getOperand(0).getValueType().isInteger() &&
|
||||
!VT.isVector()) {
|
||||
N0.getOpcode() == ISD::BITCAST &&
|
||||
N0.getNode()->hasOneUse()) {
|
||||
SDValue Int = N0.getOperand(0);
|
||||
EVT IntVT = Int.getValueType();
|
||||
if (IntVT.isInteger() && !IntVT.isVector()) {
|
||||
APInt SignMask;
|
||||
if (N0.getValueType().isVector()) {
|
||||
// For a vector, get a mask such as 0x7f... per scalar element
|
||||
// and splat it.
|
||||
SignMask = ~APInt::getSignBit(N0.getValueType().getScalarSizeInBits());
|
||||
SignMask = APInt::getSplat(IntVT.getSizeInBits(), SignMask);
|
||||
} else {
|
||||
// For a scalar, just generate 0x7f...
|
||||
SignMask = ~APInt::getSignBit(IntVT.getSizeInBits());
|
||||
}
|
||||
Int = DAG.getNode(ISD::AND, SDLoc(N0), IntVT, Int,
|
||||
DAG.getConstant(~APInt::getSignBit(IntVT.getSizeInBits()), IntVT));
|
||||
DAG.getConstant(SignMask, IntVT));
|
||||
AddToWorklist(Int.getNode());
|
||||
return DAG.getNode(ISD::BITCAST, SDLoc(N),
|
||||
N->getValueType(0), Int);
|
||||
return DAG.getNode(ISD::BITCAST, SDLoc(N), N->getValueType(0), Int);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user