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
This commit is contained in:
Petar Jovanovic 2015-03-23 12:28:13 +00:00
parent eb7e9ccad8
commit 15863e5e5f
6 changed files with 235 additions and 4 deletions

View File

@ -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()).

View File

@ -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);
}

View File

@ -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,

View File

@ -475,6 +475,8 @@ namespace llvm {
const SmallVectorImpl<SDValue> &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;

View File

@ -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

View File

@ -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" }