Index: lib/CodeGen/SelectionDAG/LegalizeDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1652,21 +1652,40 @@ /// The resultant code need not be legal. SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, EVT SlotVT, EVT DestVT, const SDLoc &dl) { - // Create the stack frame object. + + unsigned SrcSize = SrcOp.getValueSizeInBits(); + unsigned SlotSize = SlotVT.getSizeInBits(); + unsigned DestSize = DestVT.getSizeInBits(); + Type *DestType = DestVT.getTypeForEVT(*DAG.getContext()); unsigned SrcAlign = DAG.getDataLayout().getPrefTypeAlignment( SrcOp.getValueType().getTypeForEVT(*DAG.getContext())); - SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign); + unsigned DestAlign = DAG.getDataLayout().getPrefTypeAlignment(DestType); + + // Before we allocate space on the stack, see we already have an + // equivalent store to another location and leverage that. + + for (SDNode *U : SrcOp->uses()) { + if (MemSDNode *SNode = dyn_cast(U)) + if (SNode->getOpcode() == ISD::STORE && SNode->getOperand(1) == SrcOp && + SlotVT.bitsEq(SNode->getMemoryVT())) { + if (SlotSize == DestSize) + return DAG.getLoad(DestVT, dl, SDValue(SNode, 0), + SNode->getOperand(2), SNode->getPointerInfo(), + DestAlign); + assert(SlotSize < DestSize && "Unknown extension!"); + return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, SDValue(SNode, 0), + SNode->getOperand(2), SNode->getPointerInfo(), + SlotVT, DestAlign); + } + } + // Create the stack frame object. + SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign); FrameIndexSDNode *StackPtrFI = cast(FIPtr); int SPFI = StackPtrFI->getIndex(); MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(DAG.getMachineFunction(), SPFI); - unsigned SrcSize = SrcOp.getValueSizeInBits(); - unsigned SlotSize = SlotVT.getSizeInBits(); - unsigned DestSize = DestVT.getSizeInBits(); - Type *DestType = DestVT.getTypeForEVT(*DAG.getContext()); - unsigned DestAlign = DAG.getDataLayout().getPrefTypeAlignment(DestType); // Emit a store to the stack slot. Use a truncstore if the input value is // later than DestVT. Index: test/CodeGen/PowerPC/share-bitcast-stores.ll =================================================================== --- /dev/null +++ test/CodeGen/PowerPC/share-bitcast-stores.ll @@ -0,0 +1,22 @@ +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -O0 -fast-isel=false -mattr=-vsx < %s | FileCheck %s +; RUN: llc -verify-machineinstrs -mcpu=pwr7 -O0 -fast-isel=false -mattr=-vsx < %s | FileCheck -check-prefix=CHECKSAFE %s + +; Verify that bitcasts realized as store-load pairs don't emit extra stores if viable one already exists. + +target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-v128:128:128-n32:64" +target triple = "powerpc64-unknown-linux-gnu" + +@number64 = global i64 10, align 8 + +define double @f64toi64(i64 %a) { +; We should never see a negative offset store +; CHECKSAFE-LABEL: f64toi64 +; CHECKSAFE-NOT: std {{[0-9]+}, -{{.*}} +; CHECK-LABEL: f64toi64 +; CHECK: std 3, 0(4) +; CHECK-NEXT: lfd 1, 0(4) +entry: + store i64 %a, i64* @number64 + %0 = bitcast i64 %a to double + ret double %0 +}