[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