This code lives in DAGCombiner.cpp:<div><br></div><div>-------------<br><div><div> // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr'</div><div> if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Value)) {</div>
<div> // NOTE: If the original store is volatile, this transform must not increase</div><div> // the number of stores. For example, on x86-32 an f64 can be stored in one</div><div> // processor operation but an i64 (which is not legal) requires two. So the</div>
<div> // transform should not be done in this case.</div><div> if (Value.getOpcode() != ISD::TargetConstantFP) {</div><div> SDValue Tmp;</div><div> switch (CFP->getValueType(0).getSimpleVT().SimpleTy) {</div>
<div> default: llvm_unreachable("Unknown FP type");</div><div> case MVT::f80: // We don't do this for these yet.</div><div> case MVT::f128:</div><div> case MVT::ppcf128:</div><div> break;</div>
<div> case MVT::f32:</div><div> if ((isTypeLegal(MVT::i32) && !LegalOperations && !ST->isVolatile()) ||</div><div> TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) {</div><div>
Tmp = DAG.getConstant((uint32_t)CFP->getValueAPF().</div><div> bitcastToAPInt().getZExtValue(), MVT::i32);</div><div> return DAG.getStore(Chain, N->getDebugLoc(), Tmp,</div>
<div> Ptr, ST->getPointerInfo(), ST->isVolatile(),</div><div> ST->isNonTemporal(), ST->getAlignment());</div><div> }</div><div> break;</div>
-------------</div></div><div><br></div><div>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)</div>
<div><br></div><div>--------------</div><div><div>BB#0: derived from LLVM BB %entry</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>%vreg0<def> = MOV_I32_RI 1; I32RC:%vreg0</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>%X0<def> = COPY %vreg0; I32RC:%vreg0</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>%vreg1<def> = MOV_I32_RI 0; I32RC:%vreg1</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>%X1<def> = COPY %vreg1; I32RC:%vreg1</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>%X2<def> = COPY %vreg1; I32RC:%vreg1</div><div><span class="Apple-tab-span" style="white-space:pre"> </span>RET</div><div><br></div><div># End machine code for function foo</div>
<div><br></div><div>********** SIMPLE REGISTER COALESCING **********</div><div>********** Function: foo</div><div>********** JOINING INTERVALS ***********</div><div>entry:</div><div>32L<span class="Apple-tab-span" style="white-space:pre"> </span>%X0<def> = COPY %vreg0<kill>; I32RC:%vreg0</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>Not coalescable.</div></div><div>--------------</div><div><br></div><div>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.</div>
<div><br></div><div>Or, if I'm just not approaching the machine code/setup correctly, please let me know that too. :)</div><div><br></div><div>Thanks,</div><div>Joe</div>