Joe Matarazzo
2012-Feb-10 01:23 UTC
[LLVMdev] Prevent DAG combiner from changing "store ConstFP, addr" to integer store
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/20120209/a2db306c/attachment.html>
Joe Matarazzo
2012-Feb-13 18:50 UTC
[LLVMdev] Prevent DAG combiner from changing "store ConstFP, addr" to integer store
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>