[LLVMdev] Prevent DAG combiner from changing "store ConstFP, addr" to integer store

Joe Matarazzo joe.matarazzo at gmail.com
Thu Feb 9 17:23:19 PST 2012

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
    // 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:
      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());

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

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

# End machine code for function foo

********** SIMPLE REGISTER COALESCING **********
********** Function: foo
********** JOINING INTERVALS ***********
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. :)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120209/a2db306c/attachment.html>

More information about the llvm-dev mailing list