forked from OSchip/llvm-project
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 llvm-svn: 232943
This commit is contained in:
parent
a2e5b2cea7
commit
5b4362276b
|
@ -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()).
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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" }
|
Loading…
Reference in New Issue