[LLVMdev] Prevent DAG combiner from changing "store ConstFP, addr" to integer store
Joe Matarazzo
joe.matarazzo at gmail.com
Mon Feb 13 10:50:11 PST 2012
I haven't gotten a response on my previous question, below, so I tried the
following change to SelectionDAGBuilder.cpp:
@@ -1026,7 +1026,8 @@
return DAG.getConstant(0, TLI.getPointerTy());
if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C))
- return DAG.getConstantFP(*CFP, VT);
+ return DAG.getConstantFP(
+ *CFP, VT, TLI.isFPImmLegal(CFP->getValueAPF(),
EVT::getEVT(V->getType())));
if (isa<UndefValue>(C) && !V->getType()->isAggregateType())
return DAG.getUNDEF(VT);
That is, if FP immediates are ok in the target, generate the constant as a
target constant. Is this an acceptable change?
On Thu, Feb 9, 2012 at 5:23 PM, Joe Matarazzo <joe.matarazzo at gmail.com>wrote:
> This code lives in DAGCombiner.cpp:
>
> -------------
> // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr'
> if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Value)) {
> // NOTE: If the original store is volatile, this transform must not
> increase
> // the number of stores. For example, on x86-32 an f64 can be stored
> in one
> // processor operation but an i64 (which is not legal) requires two.
> So the
> // transform should not be done in this case.
> if (Value.getOpcode() != ISD::TargetConstantFP) {
> SDValue Tmp;
> switch (CFP->getValueType(0).getSimpleVT().SimpleTy) {
> default: llvm_unreachable("Unknown FP type");
> case MVT::f80: // We don't do this for these yet.
> case MVT::f128:
> case MVT::ppcf128:
> break;
> case MVT::f32:
> if ((isTypeLegal(MVT::i32) && !LegalOperations &&
> !ST->isVolatile()) ||
> TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) {
> Tmp = DAG.getConstant((uint32_t)CFP->getValueAPF().
> bitcastToAPInt().getZExtValue(), MVT::i32);
> return DAG.getStore(Chain, N->getDebugLoc(), Tmp,
> Ptr, ST->getPointerInfo(), ST->isVolatile(),
> ST->isNonTemporal(), ST->getAlignment());
> }
> break;
> -------------
>
> What would be the proper way to inhibit this change? In my target (a
> custom b/e) MVT::i32 is a legal type, and I have a "store MVT::i32"
> instruction, but I want to later promote the store to a MOV (in a custom
> lowering step), and this code above is changing the register class, such
> that it won't coalesce. The debug output looks like this (%Xn are phys regs
> in F32RC regclass)
>
> --------------
> BB#0: derived from LLVM BB %entry
> %vreg0<def> = MOV_I32_RI 1; I32RC:%vreg0
> %X0<def> = COPY %vreg0; I32RC:%vreg0
> %vreg1<def> = MOV_I32_RI 0; I32RC:%vreg1
> %X1<def> = COPY %vreg1; I32RC:%vreg1
> %X2<def> = COPY %vreg1; I32RC:%vreg1
> RET
>
> # End machine code for function foo
>
> ********** SIMPLE REGISTER COALESCING **********
> ********** Function: foo
> ********** JOINING INTERVALS ***********
> entry:
> 32L %X0<def> = COPY %vreg0<kill>; I32RC:%vreg0
> Not coalescable.
> --------------
>
> I thought about using the ISD::TargetConstantFP designation on the source,
> but how does that get set? I couldn't see it used anywhere in the up-front
> Lower stage of SelectionDAG creation.
>
> Or, if I'm just not approaching the machine code/setup correctly, please
> let me know that too. :)
>
> Thanks,
> Joe
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120213/e9657879/attachment.html>
More information about the llvm-dev
mailing list