Commit c4508791 by Jim Stichnoth

Subzero: Clean up the runtime implementation.

The runtime helpers are given more consistent names: __Sz_<bitcode>_<type1>_<type2> Missing helpers (various vector bitcasts) are implemented. We'd prefer to avoid calling external library functions, e.g. in compiler-rt, but even llc uses these helpers for some bitcode on x86-32, so the alternative is to copy their implementation into Subzero's runtime. BUG= none R=mtrofin@chromium.org Review URL: https://codereview.chromium.org/961413002
parent 739327ab
......@@ -16,6 +16,8 @@ def Translate(ll_files, extra_args, obj, verbose):
shellcmd(['cat'] + ll_files + ['|',
'pnacl-llc',
'-externalize',
'-function-sections',
'-O2',
'-filetype=obj',
'-bitcode-format=llvm',
'-o', obj
......
......@@ -15,7 +15,6 @@
//===----------------------------------------------------------------------===//
#include <stdint.h>
#include <stdlib.h>
// TODO(stichnot): The various NaN cross tests try to map Subzero's
// undefined behavior to the same as llc's undefined behavior, as
......@@ -24,44 +23,57 @@
// for different targets. It would be better to find a more
// appropriate set of llc options when building the Subzero runtime.
//
// We test for NaN using "value==value" instead of using isnan(value)
// We test for NaN using "Value==Value" instead of using isnan(Value)
// to avoid an external dependency on fpclassify().
uint32_t cvtftoui32(float value) {
if (value == value) // NaNaN
return (uint32_t)value;
uint32_t __Sz_fptoui_f32_i32(float Value) {
if (Value == Value) // NaNaN
return (uint32_t)Value;
return 0x80000000;
}
uint32_t cvtdtoui32(double value) {
if (value == value) // NaNaN
return (uint32_t)value;
uint32_t __Sz_fptoui_f64_i32(double Value) {
if (Value == Value) // NaNaN
return (uint32_t)Value;
return 0x80000000;
}
int64_t cvtftosi64(float value) { return (int64_t)value; }
uint64_t __Sz_fptoui_f32_i64(float Value) { return (uint64_t)Value; }
int64_t cvtdtosi64(double value) { return (int64_t)value; }
uint64_t __Sz_fptoui_f64_i64(double Value) { return (uint64_t)Value; }
uint64_t cvtftoui64(float value) { return (uint64_t)value; }
int64_t __Sz_fptosi_f32_i64(float Value) { return (int64_t)Value; }
uint64_t cvtdtoui64(double value) { return (uint64_t)value; }
int64_t __Sz_fptosi_f64_i64(double Value) { return (int64_t)Value; }
float cvtui32tof(uint32_t value) { return (float)value; }
float __Sz_uitofp_i32_f32(uint32_t Value) { return (float)Value; }
float cvtsi64tof(int64_t value) { return (float)value; }
float __Sz_uitofp_i64_f32(uint64_t Value) { return (float)Value; }
float cvtui64tof(uint64_t value) { return (float)value; }
double __Sz_uitofp_i32_f64(uint32_t Value) { return (double)Value; }
double cvtui32tod(uint32_t value) { return (double)value; }
double __Sz_uitofp_i64_f64(uint64_t Value) { return (double)Value; }
double cvtsi64tod(int64_t value) { return (double)value; }
float __Sz_sitofp_i64_f32(int64_t Value) { return (float)Value; }
double cvtui64tod(uint64_t value) { return (double)value; }
double __Sz_sitofp_i64_f64(int64_t Value) { return (double)Value; }
/* TODO(stichnot):
Sz_bitcast_v8i1_to_i8
Sz_bitcast_v16i1_to_i16
Sz_bitcast_i8_to_v8i1
Sz_bitcast_i16_to_v16i1
*/
// Other helper calls emitted by Subzero but not implemented here:
// Compiler-rt:
// __udivdi3 - udiv i64
// __divdi3 - sdiv i64
// __umoddi3 - urem i64
// __moddi3 - srem i64
// __popcountsi2 - call @llvm.ctpop.i32
// __popcountdi2 - call @llvm.ctpop.i64
// libm:
// fmodf - frem f32
// fmod - frem f64
// libc:
// setjmp - call @llvm.nacl.setjmp
// longjmp - call @llvm.nacl.longjmp
// memcpy - call @llvm.memcpy.p0i8.p0i8.i32
// memmove - call @llvm.memmove.p0i8.p0i8.i32
// memset - call @llvm.memset.p0i8.i32
// unsandboxed_irt:
// __nacl_read_tp
......@@ -14,14 +14,38 @@
;;
;;===----------------------------------------------------------------------===;;
define <4 x float> @Sz_uitofp_v4i32(<4 x i32> %a) {
define <4 x float> @__Sz_uitofp_4xi32_4xf32(<4 x i32> %a) {
entry:
%0 = uitofp <4 x i32> %a to <4 x float>
ret <4 x float> %0
}
define <4 x i32> @Sz_fptoui_v4f32(<4 x float> %a) {
define <4 x i32> @__Sz_fptoui_4xi32_f32(<4 x float> %a) {
entry:
%0 = fptoui <4 x float> %a to <4 x i32>
ret <4 x i32> %0
}
define i8 @__Sz_bitcast_8xi1_i8(<8 x i1> %a) {
entry:
%0 = bitcast <8 x i1> %a to i8
ret i8 %0
}
define i16 @__Sz_bitcast_16xi1_i16(<16 x i1> %a) {
entry:
%0 = bitcast <16 x i1> %a to i16
ret i16 %0
}
define <8 x i1> @__Sz_bitcast_i8_8xi1(i8 %a) {
entry:
%0 = bitcast i8 %a to <8 x i1>
ret <8 x i1> %0
}
define <16 x i1> @__Sz_bitcast_i16_16xi1(i16 %a) {
entry:
%0 = bitcast i16 %a to <16 x i1>
ret <16 x i1> %0
}
......@@ -252,6 +252,40 @@ protected:
int32_t StackAdjustment;
LoweringContext Context;
// Runtime helper function names
const static constexpr char *H_bitcast_16xi1_i16 = "__Sz_bitcast_16xi1_i16";
const static constexpr char *H_bitcast_8xi1_i8 = "__Sz_bitcast_8xi1_i8";
const static constexpr char *H_bitcast_i16_16xi1 = "__Sz_bitcast_i16_16xi1";
const static constexpr char *H_bitcast_i8_8xi1 = "__Sz_bitcast_i8_8xi1";
const static constexpr char *H_call_ctpop_i32 = "__popcountsi2";
const static constexpr char *H_call_ctpop_i64 = "__popcountdi2";
const static constexpr char *H_call_longjmp = "longjmp";
const static constexpr char *H_call_memcpy = "memcpy";
const static constexpr char *H_call_memmove = "memmove";
const static constexpr char *H_call_memset = "memset";
const static constexpr char *H_call_read_tp = "__nacl_read_tp";
const static constexpr char *H_call_setjmp = "setjmp";
const static constexpr char *H_fptosi_f32_i64 = "__Sz_fptosi_f32_i64";
const static constexpr char *H_fptosi_f64_i64 = "__Sz_fptosi_f64_i64";
const static constexpr char *H_fptoui_4xi32_f32 = "__Sz_fptoui_4xi32_f32";
const static constexpr char *H_fptoui_f32_i32 = "__Sz_fptoui_f32_i32";
const static constexpr char *H_fptoui_f32_i64 = "__Sz_fptoui_f32_i64";
const static constexpr char *H_fptoui_f64_i32 = "__Sz_fptoui_f64_i32";
const static constexpr char *H_fptoui_f64_i64 = "__Sz_fptoui_f64_i64";
const static constexpr char *H_frem_f32 = "fmodf";
const static constexpr char *H_frem_f64 = "fmod";
const static constexpr char *H_sdiv_i64 = "__divdi3";
const static constexpr char *H_sitofp_i64_f32 = "__Sz_sitofp_i64_f32";
const static constexpr char *H_sitofp_i64_f64 = "__Sz_sitofp_i64_f64";
const static constexpr char *H_srem_i64 = "__moddi3";
const static constexpr char *H_udiv_i64 = "__udivdi3";
const static constexpr char *H_uitofp_4xi32_4xf32 = "__Sz_uitofp_4xi32_4xf32";
const static constexpr char *H_uitofp_i32_f32 = "__Sz_uitofp_i32_f32";
const static constexpr char *H_uitofp_i32_f64 = "__Sz_uitofp_i32_f64";
const static constexpr char *H_uitofp_i64_f32 = "__Sz_uitofp_i64_f32";
const static constexpr char *H_uitofp_i64_f64 = "__Sz_uitofp_i64_f64";
const static constexpr char *H_urem_i64 = "__umoddi3";
private:
int32_t SnapshotStackAdjustment;
};
......
......@@ -1342,28 +1342,28 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
} break;
case InstArithmetic::Udiv: {
const SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall("__udivdi3", Dest, MaxSrcs);
InstCall *Call = makeHelperCall(H_udiv_i64, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
Call->addArg(Inst->getSrc(1));
lowerCall(Call);
} break;
case InstArithmetic::Sdiv: {
const SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall("__divdi3", Dest, MaxSrcs);
InstCall *Call = makeHelperCall(H_sdiv_i64, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
Call->addArg(Inst->getSrc(1));
lowerCall(Call);
} break;
case InstArithmetic::Urem: {
const SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall("__umoddi3", Dest, MaxSrcs);
InstCall *Call = makeHelperCall(H_urem_i64, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
Call->addArg(Inst->getSrc(1));
lowerCall(Call);
} break;
case InstArithmetic::Srem: {
const SizeT MaxSrcs = 2;
InstCall *Call = makeHelperCall("__moddi3", Dest, MaxSrcs);
InstCall *Call = makeHelperCall(H_srem_i64, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
Call->addArg(Inst->getSrc(1));
lowerCall(Call);
......@@ -1664,8 +1664,9 @@ void TargetX8632::lowerArithmetic(const InstArithmetic *Inst) {
case InstArithmetic::Frem: {
const SizeT MaxSrcs = 2;
Type Ty = Dest->getType();
InstCall *Call = makeHelperCall(
isFloat32Asserting32Or64(Ty) ? "fmodf" : "fmod", Dest, MaxSrcs);
InstCall *Call =
makeHelperCall(isFloat32Asserting32Or64(Ty) ? H_frem_f32 : H_frem_f64,
Dest, MaxSrcs);
Call->addArg(Src0);
Call->addArg(Src1);
return lowerCall(Call);
......@@ -2097,10 +2098,10 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
split64(Dest);
const SizeT MaxSrcs = 1;
Type SrcType = Inst->getSrc(0)->getType();
InstCall *Call = makeHelperCall(
isFloat32Asserting32Or64(SrcType) ? "cvtftosi64" : "cvtdtosi64", Dest,
MaxSrcs);
// TODO: Call the correct compiler-rt helper function.
InstCall *Call =
makeHelperCall(isFloat32Asserting32Or64(SrcType) ? H_fptosi_f32_i64
: H_fptosi_f64_i64,
Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
lowerCall(Call);
} else {
......@@ -2120,7 +2121,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
assert(Dest->getType() == IceType_v4i32 &&
Inst->getSrc(0)->getType() == IceType_v4f32);
const SizeT MaxSrcs = 1;
InstCall *Call = makeHelperCall("Sz_fptoui_v4f32", Dest, MaxSrcs);
InstCall *Call = makeHelperCall(H_fptoui_4xi32_f32, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
lowerCall(Call);
} else if (Dest->getType() == IceType_i64 ||
......@@ -2130,11 +2131,14 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
const SizeT MaxSrcs = 1;
Type DestType = Dest->getType();
Type SrcType = Inst->getSrc(0)->getType();
IceString DstSubstring = (isInt32Asserting32Or64(DestType) ? "32" : "64");
IceString SrcSubstring = (isFloat32Asserting32Or64(SrcType) ? "f" : "d");
// Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64
IceString TargetString = "cvt" + SrcSubstring + "toui" + DstSubstring;
// TODO: Call the correct compiler-rt helper function.
IceString TargetString;
if (isInt32Asserting32Or64(DestType)) {
TargetString = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i32
: H_fptoui_f64_i32;
} else {
TargetString = isFloat32Asserting32Or64(SrcType) ? H_fptoui_f32_i64
: H_fptoui_f64_i64;
}
InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
Call->addArg(Inst->getSrc(0));
lowerCall(Call);
......@@ -2163,9 +2167,10 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// Use a helper for x86-32.
const SizeT MaxSrcs = 1;
Type DestType = Dest->getType();
InstCall *Call = makeHelperCall(
isFloat32Asserting32Or64(DestType) ? "cvtsi64tof" : "cvtsi64tod",
Dest, MaxSrcs);
InstCall *Call =
makeHelperCall(isFloat32Asserting32Or64(DestType) ? H_sitofp_i64_f32
: H_sitofp_i64_f64,
Dest, MaxSrcs);
// TODO: Call the correct compiler-rt helper function.
Call->addArg(Inst->getSrc(0));
lowerCall(Call);
......@@ -2190,7 +2195,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
assert(Dest->getType() == IceType_v4f32 &&
Src0->getType() == IceType_v4i32);
const SizeT MaxSrcs = 1;
InstCall *Call = makeHelperCall("Sz_uitofp_v4i32", Dest, MaxSrcs);
InstCall *Call = makeHelperCall(H_uitofp_4xi32_4xf32, Dest, MaxSrcs);
Call->addArg(Src0);
lowerCall(Call);
} else if (Src0->getType() == IceType_i64 ||
......@@ -2199,12 +2204,14 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
// i32 on x86-32.
const SizeT MaxSrcs = 1;
Type DestType = Dest->getType();
IceString SrcSubstring =
(isInt32Asserting32Or64(Src0->getType()) ? "32" : "64");
IceString DstSubstring = (isFloat32Asserting32Or64(DestType) ? "f" : "d");
// Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod
IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring;
// TODO: Call the correct compiler-rt helper function.
IceString TargetString;
if (isInt32Asserting32Or64(Src0->getType())) {
TargetString = isFloat32Asserting32Or64(DestType) ? H_uitofp_i32_f32
: H_uitofp_i32_f64;
} else {
TargetString = isFloat32Asserting32Or64(DestType) ? H_uitofp_i64_f32
: H_uitofp_i64_f64;
}
InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
Call->addArg(Src0);
lowerCall(Call);
......@@ -2236,13 +2243,13 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
llvm_unreachable("Unexpected Bitcast dest type");
case IceType_i8: {
assert(Src0->getType() == IceType_v8i1);
InstCall *Call = makeHelperCall("Sz_bitcast_v8i1_to_i8", Dest, 1);
InstCall *Call = makeHelperCall(H_bitcast_8xi1_i8, Dest, 1);
Call->addArg(Src0);
lowerCall(Call);
} break;
case IceType_i16: {
assert(Src0->getType() == IceType_v16i1);
InstCall *Call = makeHelperCall("Sz_bitcast_v16i1_to_i16", Dest, 1);
InstCall *Call = makeHelperCall(H_bitcast_16xi1_i16, Dest, 1);
Call->addArg(Src0);
lowerCall(Call);
} break;
......@@ -2330,7 +2337,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
} break;
case IceType_v8i1: {
assert(Src0->getType() == IceType_i8);
InstCall *Call = makeHelperCall("Sz_bitcast_i8_to_v8i1", Dest, 1);
InstCall *Call = makeHelperCall(H_bitcast_i8_8xi1, Dest, 1);
Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
// Arguments to functions are required to be at least 32 bits wide.
lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
......@@ -2339,7 +2346,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
} break;
case IceType_v16i1: {
assert(Src0->getType() == IceType_i16);
InstCall *Call = makeHelperCall("Sz_bitcast_i16_to_v16i1", Dest, 1);
InstCall *Call = makeHelperCall(H_bitcast_i16_16xi1, Dest, 1);
Variable *Src0AsI32 = Func->makeVariable(stackSlotType());
// Arguments to functions are required to be at least 32 bits wide.
lowerCast(InstCast::create(Func, InstCast::Zext, Src0AsI32, Src0));
......@@ -3013,10 +3020,10 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
case Intrinsics::Ctpop: {
Variable *Dest = Instr->getDest();
Operand *Val = Instr->getArg(0);
InstCall *Call =
makeHelperCall(isInt32Asserting32Or64(Val->getType()) ? "__popcountsi2"
: "__popcountdi2",
Dest, 1);
InstCall *Call = makeHelperCall(isInt32Asserting32Or64(Val->getType())
? H_call_ctpop_i32
: H_call_ctpop_i64,
Dest, 1);
Call->addArg(Val);
lowerCall(Call);
// The popcount helpers always return 32-bit values, while the intrinsic's
......@@ -3066,7 +3073,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return;
}
case Intrinsics::Longjmp: {
InstCall *Call = makeHelperCall("longjmp", nullptr, 2);
InstCall *Call = makeHelperCall(H_call_longjmp, nullptr, 2);
Call->addArg(Instr->getArg(0));
Call->addArg(Instr->getArg(1));
lowerCall(Call);
......@@ -3075,7 +3082,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
case Intrinsics::Memcpy: {
// In the future, we could potentially emit an inline memcpy/memset, etc.
// for intrinsic calls w/ a known length.
InstCall *Call = makeHelperCall("memcpy", nullptr, 3);
InstCall *Call = makeHelperCall(H_call_memcpy, nullptr, 3);
Call->addArg(Instr->getArg(0));
Call->addArg(Instr->getArg(1));
Call->addArg(Instr->getArg(2));
......@@ -3083,7 +3090,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
return;
}
case Intrinsics::Memmove: {
InstCall *Call = makeHelperCall("memmove", nullptr, 3);
InstCall *Call = makeHelperCall(H_call_memmove, nullptr, 3);
Call->addArg(Instr->getArg(0));
Call->addArg(Instr->getArg(1));
Call->addArg(Instr->getArg(2));
......@@ -3098,7 +3105,7 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
assert(ValOp->getType() == IceType_i8);
Variable *ValExt = Func->makeVariable(stackSlotType());
lowerCast(InstCast::create(Func, InstCast::Zext, ValExt, ValOp));
InstCall *Call = makeHelperCall("memset", nullptr, 3);
InstCall *Call = makeHelperCall(H_call_memset, nullptr, 3);
Call->addArg(Instr->getArg(0));
Call->addArg(ValExt);
Call->addArg(Instr->getArg(2));
......@@ -3116,13 +3123,13 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) {
_mov(T, Src);
_mov(Dest, T);
} else {
InstCall *Call = makeHelperCall("__nacl_read_tp", Instr->getDest(), 0);
InstCall *Call = makeHelperCall(H_call_read_tp, Instr->getDest(), 0);
lowerCall(Call);
}
return;
}
case Intrinsics::Setjmp: {
InstCall *Call = makeHelperCall("setjmp", Instr->getDest(), 1);
InstCall *Call = makeHelperCall(H_call_setjmp, Instr->getDest(), 1);
Call->addArg(Instr->getArg(0));
lowerCall(Call);
return;
......
......@@ -207,7 +207,7 @@ entry:
ret i64 %conv
}
; CHECK-LABEL: doubleToSigned64
; CHECK: call {{.*}} R_{{.*}} cvtdtosi64
; CHECK: call {{.*}} R_{{.*}} __Sz_fptosi_f64_i64
define internal i64 @floatToSigned64(float %a) {
entry:
......@@ -215,7 +215,7 @@ entry:
ret i64 %conv
}
; CHECK-LABEL: floatToSigned64
; CHECK: call {{.*}} R_{{.*}} cvtftosi64
; CHECK: call {{.*}} R_{{.*}} __Sz_fptosi_f32_i64
define internal i64 @doubleToUnsigned64(double %a) {
entry:
......@@ -223,7 +223,7 @@ entry:
ret i64 %conv
}
; CHECK-LABEL: doubleToUnsigned64
; CHECK: call {{.*}} R_{{.*}} cvtdtoui64
; CHECK: call {{.*}} R_{{.*}} __Sz_fptoui_f64_i64
define internal i64 @floatToUnsigned64(float %a) {
entry:
......@@ -231,7 +231,7 @@ entry:
ret i64 %conv
}
; CHECK-LABEL: floatToUnsigned64
; CHECK: call {{.*}} R_{{.*}} cvtftoui64
; CHECK: call {{.*}} R_{{.*}} __Sz_fptoui_f32_i64
define internal i32 @doubleToSigned32(double %a) {
entry:
......@@ -263,7 +263,7 @@ entry:
ret i32 %conv
}
; CHECK-LABEL: doubleToUnsigned32
; CHECK: call {{.*}} R_{{.*}} cvtdtoui32
; CHECK: call {{.*}} R_{{.*}} __Sz_fptoui_f64_i32
define internal i32 @floatToUnsigned32(float %a) {
entry:
......@@ -271,7 +271,7 @@ entry:
ret i32 %conv
}
; CHECK-LABEL: floatToUnsigned32
; CHECK: call {{.*}} R_{{.*}} cvtftoui32
; CHECK: call {{.*}} R_{{.*}} __Sz_fptoui_f32_i32
define internal i32 @doubleToSigned16(double %a) {
entry:
......@@ -379,7 +379,7 @@ entry:
ret double %conv
}
; CHECK-LABEL: signed64ToDouble
; CHECK: call {{.*}} R_{{.*}} cvtsi64tod
; CHECK: call {{.*}} R_{{.*}} __Sz_sitofp_i64_f64
; CHECK: fstp QWORD
define internal float @signed64ToFloat(i64 %a) {
......@@ -388,7 +388,7 @@ entry:
ret float %conv
}
; CHECK-LABEL: signed64ToFloat
; CHECK: call {{.*}} R_{{.*}} cvtsi64tof
; CHECK: call {{.*}} R_{{.*}} __Sz_sitofp_i64_f32
; CHECK: fstp DWORD
define internal double @unsigned64ToDouble(i64 %a) {
......@@ -397,7 +397,7 @@ entry:
ret double %conv
}
; CHECK-LABEL: unsigned64ToDouble
; CHECK: call {{.*}} R_{{.*}} cvtui64tod
; CHECK: call {{.*}} R_{{.*}} __Sz_uitofp_i64_f64
; CHECK: fstp
define internal float @unsigned64ToFloat(i64 %a) {
......@@ -406,7 +406,7 @@ entry:
ret float %conv
}
; CHECK-LABEL: unsigned64ToFloat
; CHECK: call {{.*}} R_{{.*}} cvtui64tof
; CHECK: call {{.*}} R_{{.*}} __Sz_uitofp_i64_f32
; CHECK: fstp
define internal double @unsigned64ToDoubleConst() {
......@@ -417,7 +417,7 @@ entry:
; CHECK-LABEL: unsigned64ToDouble
; CHECK: mov DWORD PTR [esp+0x4],0xb3a
; CHECK: mov DWORD PTR [esp],0x73ce2ff2
; CHECK: call {{.*}} R_{{.*}} cvtui64tod
; CHECK: call {{.*}} R_{{.*}} __Sz_uitofp_i64_f64
; CHECK: fstp
define internal double @signed32ToDouble(i32 %a) {
......@@ -453,7 +453,7 @@ entry:
ret double %conv
}
; CHECK-LABEL: unsigned32ToDouble
; CHECK: call {{.*}} R_{{.*}} cvtui32tod
; CHECK: call {{.*}} R_{{.*}} __Sz_uitofp_i32_f64
; CHECK: fstp QWORD
define internal float @unsigned32ToFloat(i32 %a) {
......@@ -462,7 +462,7 @@ entry:
ret float %conv
}
; CHECK-LABEL: unsigned32ToFloat
; CHECK: call {{.*}} R_{{.*}} cvtui32tof
; CHECK: call {{.*}} R_{{.*}} __Sz_uitofp_i32_f32
; CHECK: fstp DWORD
define internal double @signed16ToDouble(i32 %a) {
......
......@@ -156,7 +156,7 @@ entry:
ret i8 %res
; CHECK-LABEL: test_bitcast_v8i1_to_i8
; CHECK: call {{.*}} R_{{.*}} Sz_bitcast_v8i1_to_i8
; CHECK: call {{.*}} R_{{.*}} __Sz_bitcast_8xi1_i8
; OPTM1-LABEL: test_bitcast_v8i1_to_i8
; OPMT1: call -4
......@@ -168,7 +168,7 @@ entry:
ret i16 %res
; CHECK-LABEL: test_bitcast_v16i1_to_i16
; CHECK: call {{.*}} R_{{.*}} Sz_bitcast_v16i1_to_i16
; CHECK: call {{.*}} R_{{.*}} __Sz_bitcast_16xi1_i16
; OPTM1-LABEL: test_bitcast_v16i1_to_i16
; OPMT1: call -4
......@@ -181,10 +181,10 @@ entry:
ret <8 x i1> %res
; CHECK-LABEL: test_bitcast_i8_to_v8i1
; CHECK: call {{.*}} R_{{.*}} Sz_bitcast_i8_to_v8i1
; CHECK: call {{.*}} R_{{.*}} __Sz_bitcast_i8_8xi1
; OPTM1-LABEL: test_bitcast_i8_to_v8i1
; OPTM1: call {{.*}} R_{{.*}} Sz_bitcast_i8_to_v8i1
; OPTM1: call {{.*}} R_{{.*}} __Sz_bitcast_i8_8xi1
}
define <16 x i1> @test_bitcast_i16_to_v16i1(i32 %arg) {
......@@ -194,8 +194,8 @@ entry:
ret <16 x i1> %res
; CHECK-LABEL: test_bitcast_i16_to_v16i1
; CHECK: call {{.*}} R_{{.*}} Sz_bitcast_i16_to_v16i1
; CHECK: call {{.*}} R_{{.*}} __Sz_bitcast_i16_16xi1
; OPTM1-LABEL: test_bitcast_i16_to_v16i1
; OPTM1: call {{.*}} R_{{.*}} Sz_bitcast_i16_to_v16i1
; OPTM1: call {{.*}} R_{{.*}} __Sz_bitcast_i16_16xi1
}
......@@ -133,7 +133,7 @@ entry:
ret <4 x i32> %res
; CHECK-LABEL: test_fptoui_v4f32_to_v4i32
; CHECK: call {{.*}} R_{{.*}} Sz_fptoui_v4f32
; CHECK: call {{.*}} R_{{.*}} __Sz_fptoui_4xi32_f32
}
; [su]itofp operations
......@@ -153,5 +153,5 @@ entry:
ret <4 x float> %res
; CHECK-LABEL: test_uitofp_v4i32_to_v4f32
; CHECK: call {{.*}} R_{{.*}} Sz_uitofp_v4i32
; CHECK: call {{.*}} R_{{.*}} __Sz_uitofp_4xi32_4xf32
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment