summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorSimon Dardis <simon.dardis@mips.com>2018-01-30 16:24:10 +0000
committerSimon Dardis <simon.dardis@mips.com>2018-01-30 16:24:10 +0000
commitdaaeaba665a45728c799304bd9c4eace7c579d50 (patch)
tree39ae54caaecf310fbefacbc41ded2e0884c30fad /llvm
parentc7945c827d55550b153df65ba7070c41e1e91b90 (diff)
downloadbcm5719-llvm-daaeaba665a45728c799304bd9c4eace7c579d50.tar.gz
bcm5719-llvm-daaeaba665a45728c799304bd9c4eace7c579d50.zip
[mips] Fix incorrect sign extension for fpowi libcall
PR36061 showed that during the expansion of ISD::FPOWI, that there was an incorrect zero extension of the integer argument which for MIPS64 would then give incorrect results. Address this with the existing mechanism for correcting sign extensions. This resolves PR36061. Thanks to James Cowgill for reporting the issue! Reviewers: atanasyan, hfinkel Differential Revision: https://reviews.llvm.org/D42537 llvm-svn: 323781
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp12
-rw-r--r--llvm/lib/Target/Mips/MipsISelLowering.cpp5
-rw-r--r--llvm/test/CodeGen/Mips/pr36061.ll65
3 files changed, 74 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index b69c362db67..76aedfec2f8 100644
--- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -1996,14 +1996,15 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext());
Entry.Node = Op;
Entry.Ty = ArgTy;
- Entry.IsSExt = isSigned;
- Entry.IsZExt = !isSigned;
+ Entry.IsSExt = TLI.shouldSignExtendTypeInLibCall(ArgVT, isSigned);
+ Entry.IsZExt = !TLI.shouldSignExtendTypeInLibCall(ArgVT, isSigned);
Args.push_back(Entry);
}
SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC),
TLI.getPointerTy(DAG.getDataLayout()));
- Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext());
+ EVT RetVT = Node->getValueType(0);
+ Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext());
// By default, the input chain to this libcall is the entry node of the
// function. If the libcall is going to be emitted as a tail call then
@@ -2022,13 +2023,14 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node,
InChain = TCChain;
TargetLowering::CallLoweringInfo CLI(DAG);
+ bool signExtend = TLI.shouldSignExtendTypeInLibCall(RetVT, isSigned);
CLI.setDebugLoc(SDLoc(Node))
.setChain(InChain)
.setLibCallee(TLI.getLibcallCallingConv(LC), RetTy, Callee,
std::move(Args))
.setTailCall(isTailCall)
- .setSExtResult(isSigned)
- .setZExtResult(!isSigned)
+ .setSExtResult(signExtend)
+ .setZExtResult(!signExtend)
.setIsPostTypeLegalization(true);
std::pair<SDValue, SDValue> CallInfo = TLI.LowerCallTo(CLI);
diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp
index 79ca9cc6b80..ba05b0f48df 100644
--- a/llvm/lib/Target/Mips/MipsISelLowering.cpp
+++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp
@@ -3507,10 +3507,9 @@ MipsTargetLowering::CanLowerReturn(CallingConv::ID CallConv,
bool
MipsTargetLowering::shouldSignExtendTypeInLibCall(EVT Type, bool IsSigned) const {
- if (Subtarget.hasMips3() && Subtarget.useSoftFloat()) {
- if (Type == MVT::i32)
+ if ((ABI.IsN32() || ABI.IsN64()) && Type == MVT::i32)
return true;
- }
+
return IsSigned;
}
diff --git a/llvm/test/CodeGen/Mips/pr36061.ll b/llvm/test/CodeGen/Mips/pr36061.ll
new file mode 100644
index 00000000000..6a9aa72aae0
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/pr36061.ll
@@ -0,0 +1,65 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -target-abi n64 | FileCheck %s --check-prefix=MIPSN64
+; RUN: llc < %s -mtriple=mips64el-unknown-linux-gnu -target-abi n32 | FileCheck %s --check-prefix=MIPSN32
+
+; Test that powi has its integer argument sign extended on mips64.
+
+declare double @llvm.powi.f64(double, i32)
+
+define double @powi(double %value, i32 %power) {
+; MIPSN64-LABEL: powi:
+; MIPSN64: # %bb.0:
+; MIPSN64-NEXT: daddiu $sp, $sp, -16
+; MIPSN64-NEXT: .cfi_def_cfa_offset 16
+; MIPSN64-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
+; MIPSN64-NEXT: .cfi_offset 31, -8
+; MIPSN64-NEXT: jal __powidf2
+; MIPSN64-NEXT: sll $5, $5, 0
+; MIPSN64-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
+; MIPSN64-NEXT: jr $ra
+; MIPSN64-NEXT: daddiu $sp, $sp, 16
+;
+; MIPSN32-LABEL: powi:
+; MIPSN32: # %bb.0:
+; MIPSN32-NEXT: addiu $sp, $sp, -16
+; MIPSN32-NEXT: .cfi_def_cfa_offset 16
+; MIPSN32-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
+; MIPSN32-NEXT: .cfi_offset 31, -8
+; MIPSN32-NEXT: jal __powidf2
+; MIPSN32-NEXT: sll $5, $5, 0
+; MIPSN32-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
+; MIPSN32-NEXT: jr $ra
+; MIPSN32-NEXT: addiu $sp, $sp, 16
+ %1 = tail call double @llvm.powi.f64(double %value, i32 %power)
+ ret double %1
+}
+
+declare float @llvm.powi.f32(float, i32)
+
+define float @powfi(float %value, i32 %power) {
+; MIPSN64-LABEL: powfi:
+; MIPSN64: # %bb.0:
+; MIPSN64-NEXT: daddiu $sp, $sp, -16
+; MIPSN64-NEXT: .cfi_def_cfa_offset 16
+; MIPSN64-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
+; MIPSN64-NEXT: .cfi_offset 31, -8
+; MIPSN64-NEXT: jal __powisf2
+; MIPSN64-NEXT: sll $5, $5, 0
+; MIPSN64-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
+; MIPSN64-NEXT: jr $ra
+; MIPSN64-NEXT: daddiu $sp, $sp, 16
+;
+; MIPSN32-LABEL: powfi:
+; MIPSN32: # %bb.0:
+; MIPSN32-NEXT: addiu $sp, $sp, -16
+; MIPSN32-NEXT: .cfi_def_cfa_offset 16
+; MIPSN32-NEXT: sd $ra, 8($sp) # 8-byte Folded Spill
+; MIPSN32-NEXT: .cfi_offset 31, -8
+; MIPSN32-NEXT: jal __powisf2
+; MIPSN32-NEXT: sll $5, $5, 0
+; MIPSN32-NEXT: ld $ra, 8($sp) # 8-byte Folded Reload
+; MIPSN32-NEXT: jr $ra
+; MIPSN32-NEXT: addiu $sp, $sp, 16
+ %1 = tail call float @llvm.powi.f32(float %value, i32 %power)
+ ret float %1
+}
OpenPOWER on IntegriCloud