Index: llvm/trunk/lib/Target/Mips/MipsSEFrameLowering.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsSEFrameLowering.cpp +++ llvm/trunk/lib/Target/Mips/MipsSEFrameLowering.cpp @@ -299,8 +299,12 @@ // register). Unfortunately, we have to make this decision before register // allocation so for now we use a spill/reload sequence for all // double-precision values in regardless of being an odd/even register. - if ((Subtarget.isABI_FPXX() && !Subtarget.hasMTHC1()) || - (FP64 && !Subtarget.useOddSPReg())) { + // + // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as + // implicit operand, so other passes (like ShrinkWrapping) are aware that + // stack is used. + if (I->getNumOperands() == 4 && I->getOperand(3).isReg() + && I->getOperand(3).getReg() == Mips::SP) { unsigned DstReg = I->getOperand(0).getReg(); unsigned LoReg = I->getOperand(1).getReg(); unsigned HiReg = I->getOperand(2).getReg(); @@ -360,9 +364,12 @@ // register). Unfortunately, we have to make this decision before register // allocation so for now we use a spill/reload sequence for all // double-precision values in regardless of being an odd/even register. - - if ((Subtarget.isABI_FPXX() && !Subtarget.hasMTHC1()) || - (FP64 && !Subtarget.useOddSPReg())) { + // + // For the cases that should be covered here MipsSEISelDAGToDAG adds $sp as + // implicit operand, so other passes (like ShrinkWrapping) are aware that + // stack is used. + if (I->getNumOperands() == 4 && I->getOperand(3).isReg() + && I->getOperand(3).getReg() == Mips::SP) { unsigned DstReg = I->getOperand(0).getReg(); unsigned SrcReg = Op1.getReg(); unsigned N = Op2.getImm(); Index: llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp +++ llvm/trunk/lib/Target/Mips/MipsSEISelDAGToDAG.cpp @@ -238,6 +238,18 @@ case Mips::WRDSP: addDSPCtrlRegOperands(true, MI, MF); break; + case Mips::BuildPairF64_64: + case Mips::ExtractElementF64_64: + if (!Subtarget->useOddSPReg()) { + MI.addOperand(MachineOperand::CreateReg(Mips::SP, false, true)); + break; + } + // fallthrough + case Mips::BuildPairF64: + case Mips::ExtractElementF64: + if (Subtarget->isABI_FPXX() && !Subtarget->hasMTHC1()) + MI.addOperand(MachineOperand::CreateReg(Mips::SP, false, true)); + break; default: replaceUsesWithZeroReg(MRI, MI); } Index: llvm/trunk/test/CodeGen/Mips/buildpairf64-extractelementf64-implicit-sp.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/buildpairf64-extractelementf64-implicit-sp.ll +++ llvm/trunk/test/CodeGen/Mips/buildpairf64-extractelementf64-implicit-sp.ll @@ -0,0 +1,32 @@ +; RUN: llc -o - %s -mtriple=mips-unknown-linux-gnu \ +; RUN: -mcpu=mips32 -mattr=+fpxx \ +; RUN: -stop-after=expand-isel-pseudos | \ +; RUN: FileCheck %s -check-prefix=FPXX-IMPLICIT-SP + +; RUN: llc -o - %s -mtriple=mips-unknown-linux-gnu \ +; RUN: -mcpu=mips32r6 -mattr=+fp64,+nooddspreg \ +; RUN: -stop-after=expand-isel-pseudos | \ +; RUN: FileCheck %s -check-prefix=FP64-IMPLICIT-SP + +; RUN: llc -o - %s -mtriple=mips-unknown-linux-gnu \ +; RUN: -mcpu=mips32r2 -mattr=+fpxx \ +; RUN: -stop-after=expand-isel-pseudos | \ +; RUN: FileCheck %s -check-prefix=NO-IMPLICIT-SP + +define double @foo2(i32 signext %v1, double %d1) { +entry: +; FPXX-IMPLICIT-SP: BuildPairF64 %{{[0-9]+}}, %{{[0-9]+}}, implicit $sp +; FPXX-IMPLICIT-SP: ExtractElementF64 killed %{{[0-9]+}}, 1, implicit $sp +; FP64-IMPLICIT-SP: BuildPairF64_64 %{{[0-9]+}}, %{{[0-9]+}}, implicit $sp +; FP64-IMPLICIT-SP: ExtractElementF64_64 killed %{{[0-9]+}}, 1, implicit $sp +; NO-IMPLICIT-SP: BuildPairF64 %{{[0-9]+}}, %{{[0-9]+}} +; NO-IMPLICIT-SP-NOT: BuildPairF64 %{{[0-9]+}}, %{{[0-9]+}}, implicit $sp +; NO-IMPLICIT-SP: ExtractElementF64 killed %{{[0-9]+}}, 1 +; NO-IMPLICIT-SP-NOT: ExtractElementF64 killed %{{[0-9]+}}, 1, implicit $sp + %conv = fptrunc double %d1 to float + %0 = tail call float @llvm.copysign.f32(float 1.000000e+00, float %conv) + %conv1 = fpext float %0 to double + ret double %conv1 +} + +declare float @llvm.copysign.f32(float, float) Index: llvm/trunk/test/CodeGen/Mips/shrink-wrap-buildpairf64-extractelementf64.mir =================================================================== --- llvm/trunk/test/CodeGen/Mips/shrink-wrap-buildpairf64-extractelementf64.mir +++ llvm/trunk/test/CodeGen/Mips/shrink-wrap-buildpairf64-extractelementf64.mir @@ -0,0 +1,150 @@ +# RUN: llc -o - %s -mtriple=mips-unknown-linux-gnu -enable-shrink-wrap=true \ +# RUN: -start-before=shrink-wrap -stop-after=prologepilog | FileCheck %s + +--- | + declare void @foo() + define void @testBuildPairF64() { + ret void + } + define void @testBuildPairF64_64() { + ret void + } + define void @testBuildPairF64implicitSp() { + ret void + } + define void @testBuildPairF64_64implicitSp() { + ret void + } + define void @testExtractElementF64() { + ret void + } + define void @testExtractElementF64_64() { + ret void + } + define void @testExtractElementF64implicitSp() { + ret void + } + define void @testExtractElementF64_64implicitSp() { + ret void + } +... +--- +name: testBuildPairF64 +# CHECK-LABEL: name: testBuildPairF64 +# CHECK: bb.0 +# CHECK-NEXT: successors +# CHECK-NEXT: {{[[:space:]]$}} +# CHECK-NEXT: BuildPairF64 +body: | + bb.0: + $d0 = BuildPairF64 $zero, $zero + bb.1: + JAL @foo, implicit-def $ra + bb.2: + RetRA +... +--- +name: testBuildPairF64_64 +# CHECK-LABEL: name: testBuildPairF64_64 +# CHECK: bb.0 +# CHECK-NEXT: successors +# CHECK-NEXT: {{[[:space:]]$}} +# CHECK-NEXT: BuildPairF64_64 +body: | + bb.0: + $d0_64 = BuildPairF64_64 $zero, $zero + bb.1: + JAL @foo, implicit-def $ra + bb.2: + RetRA +... +--- +name: testBuildPairF64implicitSp +# CHECK-LABEL: name: testBuildPairF64implicitSp +# CHECK: bb.0 +# CHECK-NEXT: successors +# CHECK-NEXT: {{[[:space:]]$}} +# CHECK-NEXT: $sp = ADDiu $sp, -{{[0-9]+}} +body: | + bb.0: + $d0 = BuildPairF64 $zero, $zero, implicit $sp + bb.1: + JAL @foo, implicit-def $ra + bb.2: + RetRA +... +--- +name: testBuildPairF64_64implicitSp +# CHECK-LABEL: name: testBuildPairF64_64implicitSp +# CHECK: bb.0 +# CHECK-NEXT: successors +# CHECK-NEXT: {{[[:space:]]$}} +# CHECK-NEXT: $sp = ADDiu $sp, -{{[0-9]+}} +body: | + bb.0: + $d0_64 = BuildPairF64_64 $zero, $zero, implicit $sp + bb.1: + JAL @foo, implicit-def $ra + bb.2: + RetRA +... +--- +name: testExtractElementF64 +# CHECK-LABEL: name: testExtractElementF64 +# CHECK: bb.0 +# CHECK-NEXT: successors +# CHECK-NEXT: {{[[:space:]]$}} +# CHECK-NEXT: ExtractElementF64 +body: | + bb.0: + $at = ExtractElementF64 $d6, 1 + bb.1: + JAL @foo, implicit-def $ra + bb.2: + RetRA +... +--- +name: testExtractElementF64_64 +# CHECK-LABEL: name: testExtractElementF64_64 +# CHECK: bb.0 +# CHECK-NEXT: successors +# CHECK-NEXT: {{[[:space:]]$}} +# CHECK-NEXT: ExtractElementF64_64 +body: | + bb.0: + $at = ExtractElementF64_64 $d12_64, 1 + bb.1: + JAL @foo, implicit-def $ra + bb.2: + RetRA +... +--- +name: testExtractElementF64implicitSp +# CHECK-LABEL: name: testExtractElementF64implicitSp +# CHECK: bb.0 +# CHECK-NEXT: successors +# CHECK-NEXT: {{[[:space:]]$}} +# CHECK-NEXT: $sp = ADDiu $sp, -{{[0-9]+}} +body: | + bb.0: + $at = ExtractElementF64 $d6, 1, implicit $sp + bb.1: + JAL @foo, implicit-def $ra + bb.2: + RetRA +... +--- +name: testExtractElementF64_64implicitSp +# CHECK-LABEL: name: testExtractElementF64_64implicitSp +# CHECK: bb.0 +# CHECK-NEXT: successors +# CHECK-NEXT: {{[[:space:]]$}} +# CHECK-NEXT: $sp = ADDiu $sp, -{{[0-9]+}} +body: | + bb.0: + $at = ExtractElementF64_64 $d12_64, 1, implicit $sp + bb.1: + JAL @foo, implicit-def $ra + bb.2: + RetRA +...