]> granicus.if.org Git - llvm/commitdiff
Merging r232943:
authorDaniel Sanders <daniel.sanders@imgtec.com>
Tue, 28 Apr 2015 09:39:55 +0000 (09:39 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Tue, 28 Apr 2015 09:39:55 +0000 (09:39 +0000)
------------------------------------------------------------------------
r232943 | petarj | 2015-03-23 12:28:13 +0000 (Mon, 23 Mar 2015) | 10 lines

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/branches/release_36@235973 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetLowering.h
lib/CodeGen/SelectionDAG/TargetLowering.cpp
lib/Target/Mips/MipsISelLowering.cpp
lib/Target/Mips/MipsISelLowering.h
test/CodeGen/Mips/mips64-f128.ll
test/CodeGen/Mips/mips64signextendsesf.ll [new file with mode: 0644]

index c5fed02e17b84381a255b89af7bfdd2d395ce096..09957b485a5ef4e87e7fc318ba4d29f7275edb4c 100644 (file)
@@ -1060,6 +1060,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()).
index 72e0aca8408043a9739449a1946d74348f9c4986..f12c035e785822b37bb8ee2d0944b4ad14b03887 100644 (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);
 }
 
index c0df9b77ededccf22f53a274384d33c563212388..bac5c17244519739016647e453dd048955cf1ebf 100644 (file)
@@ -3059,6 +3059,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,
index 4132de6dbcadd2196f3fc3e973a76b1815c693cd..4da337a61dadcc16af27854659a88c8e127d51a8 100644 (file)
@@ -472,6 +472,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;
index 6987d4ab07345288b0fe4fe99fe60c0fd4731242..f0cbbd08d79a8bbe350facd1cd72ce4b783f443a 100644 (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
 
diff --git a/test/CodeGen/Mips/mips64signextendsesf.ll b/test/CodeGen/Mips/mips64signextendsesf.ll
new file mode 100644 (file)
index 0000000..a76388d
--- /dev/null
@@ -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" }
\ No newline at end of file