Skip to content

Commit

Permalink
Fix sign extension for MIPS64 in makeLibCall function
Browse files Browse the repository at this point in the history
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
  • Loading branch information
petar-jovanovic committed Mar 23, 2015
1 parent a2e5b2c commit 5b43622
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 4 deletions.
5 changes: 5 additions & 0 deletions llvm/include/llvm/Target/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,11 @@ class TargetLoweringBase {
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()).
Expand Down
7 changes: 4 additions & 3 deletions llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down
9 changes: 9 additions & 0 deletions llvm/lib/Target/Mips/MipsISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/Mips/MipsISelLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/CodeGen/Mips/mips64-f128.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
214 changes: 214 additions & 0 deletions llvm/test/CodeGen/Mips/mips64signextendsesf.ll
Original file line number Diff line number Diff line change
@@ -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" }

0 comments on commit 5b43622

Please sign in to comment.