From 15863e5e5f1eecedb2165690d39ff6e37968dd6a Mon Sep 17 00:00:00 2001 From: Petar Jovanovic Date: Mon, 23 Mar 2015 12:28:13 +0000 Subject: [PATCH] Fix sign extension for MIPS64 in makeLibCall function Fixing sign extension in makeLibCall for MIPS64. In MIPS64 architecture all 32 bit arguments (int, unsigned int, float 32 (soft float)) must be sign extended. This fixes test "MultiSource/Applications/oggenc/". Patch by Strahinja Petrovic. Differential Revision: http://reviews.llvm.org/D7791 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232943 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetLowering.h | 5 + lib/CodeGen/SelectionDAG/TargetLowering.cpp | 7 +- lib/Target/Mips/MipsISelLowering.cpp | 9 + lib/Target/Mips/MipsISelLowering.h | 2 + test/CodeGen/Mips/mips64-f128.ll | 2 +- test/CodeGen/Mips/mips64signextendsesf.ll | 214 ++++++++++++++++++++ 6 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 test/CodeGen/Mips/mips64signextendsesf.ll diff --git a/include/llvm/Target/TargetLowering.h b/include/llvm/Target/TargetLowering.h index fa827a1aff4..dd23d8cac56 100644 --- a/include/llvm/Target/TargetLowering.h +++ b/include/llvm/Target/TargetLowering.h @@ -1080,6 +1080,11 @@ public: return false; } + /// Returns true if arguments should be sign-extended in lib calls. + virtual bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const { + return IsSigned; + } + /// Returns true if the given (atomic) load should be expanded by the /// IR-level AtomicExpand pass into a load-linked instruction /// (through emitLoadLinked()). diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 0a3c926f0d0..c382fe0d6fb 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -96,18 +96,19 @@ TargetLowering::makeLibCall(SelectionDAG &DAG, for (unsigned i = 0; i != NumOps; ++i) { Entry.Node = Ops[i]; Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); - Entry.isSExt = isSigned; - Entry.isZExt = !isSigned; + Entry.isSExt = shouldSignExtendTypeInLibCall(Ops[i].getValueType(), isSigned); + Entry.isZExt = !shouldSignExtendTypeInLibCall(Ops[i].getValueType(), isSigned); Args.push_back(Entry); } SDValue Callee = DAG.getExternalSymbol(getLibcallName(LC), getPointerTy()); Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); TargetLowering::CallLoweringInfo CLI(DAG); + bool signExtend = shouldSignExtendTypeInLibCall(RetVT, isSigned); CLI.setDebugLoc(dl).setChain(DAG.getEntryNode()) .setCallee(getLibcallCallingConv(LC), RetTy, Callee, std::move(Args), 0) .setNoReturn(doesNotReturn).setDiscardResult(!isReturnValueUsed) - .setSExtResult(isSigned).setZExtResult(!isSigned); + .setSExtResult(signExtend).setZExtResult(!signExtend); return LowerCallTo(CLI); } diff --git a/lib/Target/Mips/MipsISelLowering.cpp b/lib/Target/Mips/MipsISelLowering.cpp index f7a7baa702c..2eebd76ce24 100644 --- a/lib/Target/Mips/MipsISelLowering.cpp +++ b/lib/Target/Mips/MipsISelLowering.cpp @@ -3032,6 +3032,15 @@ MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv, return CCInfo.CheckReturn(Outs, RetCC_Mips); } +bool +MipsTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const { + if (Subtarget.hasMips3() && Subtarget.abiUsesSoftFloat()) { + if (Type == MVT::i32) + return true; + } + return IsSigned; +} + SDValue MipsTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, diff --git a/lib/Target/Mips/MipsISelLowering.h b/lib/Target/Mips/MipsISelLowering.h index 748b1ad45bf..02efba84fcf 100644 --- a/lib/Target/Mips/MipsISelLowering.h +++ b/lib/Target/Mips/MipsISelLowering.h @@ -475,6 +475,8 @@ namespace llvm { const SmallVectorImpl &OutVals, SDLoc dl, SelectionDAG &DAG) const override; + bool shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const override; + // Inline asm support ConstraintType getConstraintType(const std::string &Constraint) const override; diff --git a/test/CodeGen/Mips/mips64-f128.ll b/test/CodeGen/Mips/mips64-f128.ll index 9dd41e389d1..0217c7cefcd 100644 --- a/test/CodeGen/Mips/mips64-f128.ll +++ b/test/CodeGen/Mips/mips64-f128.ll @@ -545,7 +545,7 @@ entry: ; ALL-LABEL: load_LD_float: ; ALL: ld $[[R0:[0-9]+]], %got_disp(gf1) -; ALL: lwu $4, 0($[[R0]]) +; ALL: lw $4, 0($[[R0]]) ; ALL: ld $25, %call16(__extendsftf2) ; ALL: jalr $25 diff --git a/test/CodeGen/Mips/mips64signextendsesf.ll b/test/CodeGen/Mips/mips64signextendsesf.ll new file mode 100644 index 00000000000..a76388ddda3 --- /dev/null +++ b/test/CodeGen/Mips/mips64signextendsesf.ll @@ -0,0 +1,214 @@ +; RUN: llc -march=mips64 -mcpu=mips64r2 -soft-float -O2 < %s | FileCheck %s + +define void @foosf() #0 { +entry: + %in = alloca float, align 4 + %out = alloca float, align 4 + store volatile float 0xBFD59E1380000000, float* %in, align 4 + %in.0.in.0. = load volatile float, float* %in, align 4 + %rintf = tail call float @rintf(float %in.0.in.0.) #1 + store volatile float %rintf, float* %out, align 4 + ret void + +; CHECK-LABEL: foosf +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare float @rintf(float) + +define float @foosf1(float* nocapture readonly %a) #0 { +entry: + %0 = load float, float* %a, align 4 + %call = tail call float @roundf(float %0) #2 + ret float %call + +; CHECK-LABEL: foosf1 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare float @roundf(float) #1 + +define float @foosf2(float* nocapture readonly %a) #0 { +entry: + %0 = load float, float* %a, align 4 + %call = tail call float @truncf(float %0) #2 + ret float %call + +; CHECK-LABEL: foosf2 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare float @truncf(float) #1 + +define float @foosf3(float* nocapture readonly %a) #0 { +entry: + %0 = load float, float* %a, align 4 + %call = tail call float @floorf(float %0) #2 + ret float %call + +; CHECK-LABEL: foosf3 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare float @floorf(float) #1 + +define float @foosf4(float* nocapture readonly %a) #0 { +entry: + %0 = load float, float* %a, align 4 + %call = tail call float @nearbyintf(float %0) #2 + ret float %call + +; CHECK-LABEL: foosf4 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare float @nearbyintf(float) #1 + +define float @foosf5(float* nocapture readonly %a) #0 { +entry: + %0 = load float, float* %a, align 4 + %mul = fmul float %0, undef + ret float %mul + +; CHECK-LABEL: foosf5 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +define float @foosf6(float* nocapture readonly %a) #0 { +entry: + %0 = load float, float* %a, align 4 + %sub = fsub float %0, undef + ret float %sub + +; CHECK-LABEL: foosf6 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +define float @foosf7(float* nocapture readonly %a) #0 { +entry: + %0 = load float, float* %a, align 4 + %add = fadd float %0, undef + ret float %add + +; CHECK-LABEL: foosf7 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +define float @foosf8(float* nocapture readonly %a) #0 { +entry: + %b = alloca float, align 4 + %b.0.b.0. = load volatile float, float* %b, align 4 + %0 = load float, float* %a, align 4 + %div = fdiv float %b.0.b.0., %0 + ret float %div + +; CHECK-LABEL: foosf8 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +define float @foosf9() #0 { +entry: + %b = alloca float, align 4 + %b.0.b.0. = load volatile float, float* %b, align 4 + %conv = fpext float %b.0.b.0. to double + %b.0.b.0.3 = load volatile float, float* %b, align 4 + %conv1 = fpext float %b.0.b.0.3 to double + %call = tail call double @pow(double %conv, double %conv1) #1 + %conv2 = fptrunc double %call to float + ret float %conv2 + +; CHECK-LABEL: foosf9 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare double @pow(double, double) #0 + +define float @foosf10() #0 { +entry: + %a = alloca float, align 4 + %a.0.a.0. = load volatile float, float* %a, align 4 + %conv = fpext float %a.0.a.0. to double + %call = tail call double @sin(double %conv) #1 + %conv1 = fptrunc double %call to float + ret float %conv1 + +; CHECK-LABEL: foosf10 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare double @sin(double) #0 + +define float @foosf11() #0 { +entry: + %b = alloca float, align 4 + %b.0.b.0. = load volatile float, float* %b, align 4 + %call = tail call float @ceilf(float %b.0.b.0.) #2 + ret float %call + +; CHECK-LABEL: foosf11 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare float @ceilf(float) #1 + +define float @foosf12() #0 { +entry: + %b = alloca float, align 4 + %a = alloca float, align 4 + %b.0.b.0. = load volatile float, float* %b, align 4 + %a.0.a.0. = load volatile float, float* %a, align 4 + %call = tail call float @fmaxf(float %b.0.b.0., float %a.0.a.0.) #2 + ret float %call + +; CHECK-LABEL: foosf12 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare float @fmaxf(float, float) #1 + +define float @foosf13() #0 { +entry: + %b = alloca float, align 4 + %a = alloca float, align 4 + %b.0.b.0. = load volatile float, float* %b, align 4 + %a.0.a.0. = load volatile float, float* %a, align 4 + %call = tail call float @fminf(float %b.0.b.0., float %a.0.a.0.) #2 + ret float %call + +; CHECK-LABEL: foosf13 +; CHECK-NOT: dsll +; CHECK-NOT: dsrl +; CHECK-NOT: lwu +} + +declare float @fminf(float, float) #1 + + +attributes #0 = { nounwind "use-soft-float"="true" } +attributes #1 = { nounwind readnone "use-soft-float"="true" } \ No newline at end of file -- 2.34.1