summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReed Kotler <rkotler@mips.com>2013-08-01 21:17:53 +0000
committerReed Kotler <rkotler@mips.com>2013-08-01 21:17:53 +0000
commit83f879ddb240ef09e5dc5dd14d2918b0ba5ad55b (patch)
treeb307dd5d642524c34f14ee249185ed73f2e496e6
parent79af384d72355dca4174e5a9ee391d38226896bc (diff)
downloadbcm5719-llvm-83f879ddb240ef09e5dc5dd14d2918b0ba5ad55b.tar.gz
bcm5719-llvm-83f879ddb240ef09e5dc5dd14d2918b0ba5ad55b.zip
Fix some issues with Mips16 floating when certain intrinsics are present.
This is actually an LLVM bug in the way it generates signatures for these when soft float is enabled. For example, floor ends up having the signature of int64(int64). The signature part is not the same as where the actual parameter types are recorded, and those ARE of course int64(int64) when soft float is enabled. (Yes, Mips16 hard float uses soft float but with different runtime rounes but then has to interoperate with Mips32 using normal floating point). This logic will eventually be moved to the Mips16HardFloat pass so it's not worth sorting out these issues in LLVM since nobody but Mips16 cares about these signatures, as far as I know, and even I won't eventually either. llvm-svn: 187613
-rw-r--r--llvm/lib/Target/Mips/Mips16ISelLowering.cpp52
-rw-r--r--llvm/test/CodeGen/Mips/fp16instrinsmc.ll368
2 files changed, 420 insertions, 0 deletions
diff --git a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
index 1ec0f2f6eb3..b3beb126ccf 100644
--- a/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
+++ b/llvm/lib/Target/Mips/Mips16ISelLowering.cpp
@@ -37,6 +37,18 @@ struct Mips16Libcall {
return std::strcmp(Name, RHS.Name) < 0;
}
};
+
+struct Mips16IntrinsicHelperType{
+ const char* Name;
+ const char* Helper;
+
+ bool operator<(const Mips16IntrinsicHelperType &RHS) const {
+ return std::strcmp(Name, RHS.Name) < 0;
+ }
+ bool operator==(const Mips16IntrinsicHelperType &RHS) const {
+ return std::strcmp(Name, RHS.Name) == 0;
+ }
+};
}
// Libcalls for which no helper is generated. Sorted by name for binary search.
@@ -77,6 +89,31 @@ static const Mips16Libcall HardFloatLibCalls[] = {
{ RTLIB::UO_F32, "__mips16_unordsf2" }
};
+static const Mips16IntrinsicHelperType Mips16IntrinsicHelper[] = {
+ {"ceil", "__mips16_call_stub_df_2"},
+ {"ceilf", "__mips16_call_stub_sf_1"},
+ {"copysign", "__mips16_call_stub_df_10"},
+ {"copysignf", "__mips16_call_stub_sf_5"},
+ {"cos", "__mips16_call_stub_df_2"},
+ {"cosf", "__mips16_call_stub_sf_1"},
+ {"exp2", "__mips16_call_stub_df_2"},
+ {"exp2f", "__mips16_call_stub_sf_1"},
+ {"floor", "__mips16_call_stub_df_2"},
+ {"floorf", "__mips16_call_stub_sf_1"},
+ {"log2", "__mips16_call_stub_df_2"},
+ {"log2f", "__mips16_call_stub_sf_1"},
+ {"nearbyint", "__mips16_call_stub_df_2"},
+ {"nearbyintf", "__mips16_call_stub_sf_1"},
+ {"rint", "__mips16_call_stub_df_2"},
+ {"rintf", "__mips16_call_stub_sf_1"},
+ {"sin", "__mips16_call_stub_df_2"},
+ {"sinf", "__mips16_call_stub_sf_1"},
+ {"sqrt", "__mips16_call_stub_df_2"},
+ {"sqrtf", "__mips16_call_stub_sf_1"},
+ {"trunc", "__mips16_call_stub_df_2"},
+ {"truncf", "__mips16_call_stub_sf_1"},
+};
+
Mips16TargetLowering::Mips16TargetLowering(MipsTargetMachine &TM)
: MipsTargetLowering(TM) {
//
@@ -398,6 +435,21 @@ getOpndList(SmallVectorImpl<SDValue> &Ops,
if (std::binary_search(HardFloatLibCalls, array_endof(HardFloatLibCalls),
Find))
LookupHelper = false;
+ else {
+ Mips16IntrinsicHelperType IntrinsicFind = {S->getSymbol(), ""};
+ // one more look at list of intrinsics
+ if (std::binary_search(Mips16IntrinsicHelper,
+ array_endof(Mips16IntrinsicHelper),
+ IntrinsicFind)) {
+ const Mips16IntrinsicHelperType *h =(std::find(Mips16IntrinsicHelper,
+ array_endof(Mips16IntrinsicHelper),
+ IntrinsicFind));
+ Mips16HelperFunction = h->Helper;
+ NeedMips16Helper = true;
+ LookupHelper = false;
+ }
+
+ }
} else if (GlobalAddressSDNode *G =
dyn_cast<GlobalAddressSDNode>(CLI.Callee)) {
Mips16Libcall Find = { RTLIB::UNKNOWN_LIBCALL,
diff --git a/llvm/test/CodeGen/Mips/fp16instrinsmc.ll b/llvm/test/CodeGen/Mips/fp16instrinsmc.ll
new file mode 100644
index 00000000000..3c01d560f7c
--- /dev/null
+++ b/llvm/test/CodeGen/Mips/fp16instrinsmc.ll
@@ -0,0 +1,368 @@
+; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -soft-float -mips16-hard-float -relocation-model=pic < %s | FileCheck %s -check-prefix=pic
+
+@x = global float 1.500000e+00, align 4
+@xn = global float -1.900000e+01, align 4
+@negone = global float -1.000000e+00, align 4
+@one = global float 1.000000e+00, align 4
+@xd = global double 0x40048B0A8EA4481E, align 8
+@xdn = global double 0xC0311F9ADD373963, align 8
+@negoned = global double -1.000000e+00, align 8
+@oned = global float 1.000000e+00, align 4
+@y = common global float 0.000000e+00, align 4
+@yd = common global double 0.000000e+00, align 8
+
+; Function Attrs: nounwind
+define void @foo1() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %1 = load float* @one, align 4
+ %call = call float @copysignf(float %0, float %1) #2
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare float @copysignf(float, float) #1
+
+; Function Attrs: nounwind
+define void @foo2() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %1 = load float* @negone, align 4
+ %call = call float @copysignf(float %0, float %1) #2
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind
+define void @foo3() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %1 = load float* @oned, align 4
+ %conv = fpext float %1 to double
+ %call = call double @copysign(double %0, double %conv) #2
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare double @copysign(double, double) #1
+
+; Function Attrs: nounwind
+define void @foo4() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %1 = load double* @negoned, align 8
+ %call = call double @copysign(double %0, double %1) #2
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind
+define void @foo5() #0 {
+entry:
+ %0 = load float* @xn, align 4
+ %call = call float @fabsf(float %0) #2
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare float @fabsf(float) #1
+
+; Function Attrs: nounwind
+define void @foo6() #0 {
+entry:
+ %0 = load double* @xdn, align 8
+ %call = call double @fabs(double %0) #2
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare double @fabs(double) #1
+
+; Function Attrs: nounwind
+define void @foo7() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @sinf(float %0) #3
+;pic: lw ${{[0-9]+}}, %call16(sinf)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind
+declare float @sinf(float) #0
+
+; Function Attrs: nounwind
+define void @foo8() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @sin(double %0) #3
+;pic: lw ${{[0-9]+}}, %call16(sin)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind
+declare double @sin(double) #0
+
+; Function Attrs: nounwind
+define void @foo9() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @cosf(float %0) #3
+;pic: lw ${{[0-9]+}}, %call16(cosf)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind
+declare float @cosf(float) #0
+
+; Function Attrs: nounwind
+define void @foo10() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @cos(double %0) #3
+;pic: lw ${{[0-9]+}}, %call16(cos)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind
+declare double @cos(double) #0
+
+; Function Attrs: nounwind
+define void @foo11() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @sqrtf(float %0) #3
+;pic: lw ${{[0-9]+}}, %call16(sqrtf)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind
+declare float @sqrtf(float) #0
+
+; Function Attrs: nounwind
+define void @foo12() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @sqrt(double %0) #3
+;pic: lw ${{[0-9]+}}, %call16(sqrt)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind
+declare double @sqrt(double) #0
+
+; Function Attrs: nounwind
+define void @foo13() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @floorf(float %0) #2
+;pic: lw ${{[0-9]+}}, %call16(floorf)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare float @floorf(float) #1
+
+; Function Attrs: nounwind
+define void @foo14() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @floor(double %0) #2
+;pic: lw ${{[0-9]+}}, %call16(floor)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare double @floor(double) #1
+
+; Function Attrs: nounwind
+define void @foo15() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @nearbyintf(float %0) #2
+;pic: lw ${{[0-9]+}}, %call16(nearbyintf)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare float @nearbyintf(float) #1
+
+; Function Attrs: nounwind
+define void @foo16() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @nearbyint(double %0) #2
+;pic: lw ${{[0-9]+}}, %call16(nearbyint)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare double @nearbyint(double) #1
+
+; Function Attrs: nounwind
+define void @foo17() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @ceilf(float %0) #2
+;pic: lw ${{[0-9]+}}, %call16(ceilf)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare float @ceilf(float) #1
+
+; Function Attrs: nounwind
+define void @foo18() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @ceil(double %0) #2
+;pic: lw ${{[0-9]+}}, %call16(ceil)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare double @ceil(double) #1
+
+; Function Attrs: nounwind
+define void @foo19() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @rintf(float %0) #2
+;pic: lw ${{[0-9]+}}, %call16(rintf)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare float @rintf(float) #1
+
+; Function Attrs: nounwind
+define void @foo20() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @rint(double %0) #2
+;pic: lw ${{[0-9]+}}, %call16(rint)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare double @rint(double) #1
+
+; Function Attrs: nounwind
+define void @foo21() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @truncf(float %0) #2
+;pic: lw ${{[0-9]+}}, %call16(truncf)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare float @truncf(float) #1
+
+; Function Attrs: nounwind
+define void @foo22() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @trunc(double %0) #2
+;pic: lw ${{[0-9]+}}, %call16(trunc)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind readnone
+declare double @trunc(double) #1
+
+; Function Attrs: nounwind
+define void @foo23() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @log2f(float %0) #3
+;pic: lw ${{[0-9]+}}, %call16(log2f)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind
+declare float @log2f(float) #0
+
+; Function Attrs: nounwind
+define void @foo24() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @log2(double %0) #3
+;pic: lw ${{[0-9]+}}, %call16(log2)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind
+declare double @log2(double) #0
+
+; Function Attrs: nounwind
+define void @foo25() #0 {
+entry:
+ %0 = load float* @x, align 4
+ %call = call float @exp2f(float %0) #3
+;pic: lw ${{[0-9]+}}, %call16(exp2f)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_sf_1)(${{[0-9]+}})
+ store float %call, float* @y, align 4
+ ret void
+}
+
+; Function Attrs: nounwind
+declare float @exp2f(float) #0
+
+; Function Attrs: nounwind
+define void @foo26() #0 {
+entry:
+ %0 = load double* @xd, align 8
+ %call = call double @exp2(double %0) #3
+;pic: lw ${{[0-9]+}}, %call16(exp2)(${{[0-9]+}})
+;pic: lw ${{[0-9]+}}, %got(__mips16_call_stub_df_2)(${{[0-9]+}})
+ store double %call, double* @yd, align 8
+ ret void
+}
+
+; Function Attrs: nounwind
+declare double @exp2(double) #0
+
+attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" }
+attributes #1 = { nounwind readnone "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" }
+attributes #2 = { nounwind readnone }
+attributes #3 = { nounwind }
OpenPOWER on IntegriCloud