]> granicus.if.org Git - llvm/commitdiff
Merging r323781:
authorHans Wennborg <hans@hanshq.net>
Fri, 2 Feb 2018 13:41:04 +0000 (13:41 +0000)
committerHans Wennborg <hans@hanshq.net>
Fri, 2 Feb 2018 13:41:04 +0000 (13:41 +0000)
------------------------------------------------------------------------
r323781 | sdardis | 2018-01-30 17:24:10 +0100 (Tue, 30 Jan 2018) | 15 lines

[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

------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@324085 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
lib/Target/Mips/MipsISelLowering.cpp
test/CodeGen/Mips/pr36061.ll [new file with mode: 0644]

index b566c232cbc338fb2c1a14c9ce2482f11a8d00d6..3a2fb0c0a8369f5a163b28c977528570c5467e34 100644 (file)
@@ -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);
index 79ca9cc6b8002c979c22a7ccbd03763cf40fd49b..ba05b0f48df79816f8fb55249b06a9b4ddbf9ba8 100644 (file)
@@ -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/test/CodeGen/Mips/pr36061.ll b/test/CodeGen/Mips/pr36061.ll
new file mode 100644 (file)
index 0000000..6a9aa72
--- /dev/null
@@ -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
+}