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
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp index 0576add..861bc0e 100644 --- a/src/IceTargetLoweringX8632.cpp +++ b/src/IceTargetLoweringX8632.cpp
@@ -1342,28 +1342,28 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ } 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 @@ } 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ _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;