| Index: src/IceTargetLoweringX86BaseImpl.h
|
| diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
|
| index d92ba88a544a93d212cff0ff8ad86835544046e7..361abab32d73ea117c8e0d16a3635f1cfe828461 100644
|
| --- a/src/IceTargetLoweringX86BaseImpl.h
|
| +++ b/src/IceTargetLoweringX86BaseImpl.h
|
| @@ -792,16 +792,16 @@ void TargetX86Base<Machine>::finishArgumentLowering(Variable *Arg,
|
| Variable *FramePtr,
|
| size_t BasicFrameOffset,
|
| size_t &InArgsSizeBytes) {
|
| - Variable *Lo = Arg->getLo();
|
| - Variable *Hi = Arg->getHi();
|
| - Type Ty = Arg->getType();
|
| - if (!Traits::Is64Bit && Lo && Hi && Ty == IceType_i64) {
|
| - assert(Lo->getType() != IceType_i64); // don't want infinite recursion
|
| - assert(Hi->getType() != IceType_i64); // don't want infinite recursion
|
| - finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes);
|
| - finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes);
|
| - return;
|
| + if (!Traits::Is64Bit) {
|
| + if (auto *Arg64On32 = llvm::dyn_cast<Variable64On32>(Arg)) {
|
| + Variable *Lo = Arg64On32->getLo();
|
| + Variable *Hi = Arg64On32->getHi();
|
| + finishArgumentLowering(Lo, FramePtr, BasicFrameOffset, InArgsSizeBytes);
|
| + finishArgumentLowering(Hi, FramePtr, BasicFrameOffset, InArgsSizeBytes);
|
| + return;
|
| + }
|
| }
|
| + Type Ty = Arg->getType();
|
| if (isVectorType(Ty)) {
|
| InArgsSizeBytes = Traits::applyStackAlignment(InArgsSizeBytes);
|
| }
|
| @@ -829,49 +829,14 @@ template <class Machine> Type TargetX86Base<Machine>::stackSlotType() {
|
|
|
| template <class Machine>
|
| template <typename T>
|
| -typename std::enable_if<!T::Is64Bit, void>::type
|
| -TargetX86Base<Machine>::split64(Variable *Var) {
|
| - switch (Var->getType()) {
|
| - default:
|
| - return;
|
| - case IceType_i64:
|
| - // TODO: Only consider F64 if we need to push each half when passing as an
|
| - // argument to a function call. Note that each half is still typed as I32.
|
| - case IceType_f64:
|
| - break;
|
| - }
|
| - Variable *Lo = Var->getLo();
|
| - Variable *Hi = Var->getHi();
|
| - if (Lo) {
|
| - assert(Hi);
|
| - return;
|
| - }
|
| - assert(Hi == nullptr);
|
| - Lo = Func->makeVariable(IceType_i32);
|
| - Hi = Func->makeVariable(IceType_i32);
|
| - if (BuildDefs::dump()) {
|
| - Lo->setName(Func, Var->getName(Func) + "__lo");
|
| - Hi->setName(Func, Var->getName(Func) + "__hi");
|
| - }
|
| - Var->setLoHi(Lo, Hi);
|
| - if (Var->getIsArg()) {
|
| - Lo->setIsArg();
|
| - Hi->setIsArg();
|
| - }
|
| -}
|
| -
|
| -template <class Machine>
|
| -template <typename T>
|
| typename std::enable_if<!T::Is64Bit, Operand>::type *
|
| TargetX86Base<Machine>::loOperand(Operand *Operand) {
|
| assert(Operand->getType() == IceType_i64 ||
|
| Operand->getType() == IceType_f64);
|
| if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
|
| return Operand;
|
| - if (auto *Var = llvm::dyn_cast<Variable>(Operand)) {
|
| - split64(Var);
|
| - return Var->getLo();
|
| - }
|
| + if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand))
|
| + return Var64On32->getLo();
|
| if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
|
| auto *ConstInt = llvm::dyn_cast<ConstantInteger32>(
|
| Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue())));
|
| @@ -899,10 +864,8 @@ TargetX86Base<Machine>::hiOperand(Operand *Operand) {
|
| Operand->getType() == IceType_f64);
|
| if (Operand->getType() != IceType_i64 && Operand->getType() != IceType_f64)
|
| return Operand;
|
| - if (auto *Var = llvm::dyn_cast<Variable>(Operand)) {
|
| - split64(Var);
|
| - return Var->getHi();
|
| - }
|
| + if (auto *Var64On32 = llvm::dyn_cast<Variable64On32>(Operand))
|
| + return Var64On32->getHi();
|
| if (auto *Const = llvm::dyn_cast<ConstantInteger64>(Operand)) {
|
| auto *ConstInt = llvm::dyn_cast<ConstantInteger32>(
|
| Ctx->getConstantInt32(static_cast<int32_t>(Const->getValue() >> 32)));
|
| @@ -2006,12 +1969,6 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
|
| _cvt(T, Src0RM, Traits::Insts::Cvt::Tps2dq);
|
| _movp(Dest, T);
|
| } else if (!Traits::Is64Bit && Dest->getType() == IceType_i64) {
|
| - // Use a helper for converting floating-point values to 64-bit integers.
|
| - // SSE2 appears to have no way to convert from xmm registers to something
|
| - // like the edx:eax register pair, and gcc and clang both want to use x87
|
| - // instructions complete with temporary manipulation of the status word.
|
| - // This helper is not needed for x86-64.
|
| - split64(Dest);
|
| const SizeT MaxSrcs = 1;
|
| Type SrcType = Inst->getSrc(0)->getType();
|
| InstCall *Call =
|
| @@ -2051,8 +2008,6 @@ void TargetX86Base<Machine>::lowerCast(const InstCast *Inst) {
|
| } else if (Dest->getType() == IceType_i64 ||
|
| (!Traits::Is64Bit && Dest->getType() == IceType_i32)) {
|
| // Use a helper for both x86-32 and x86-64.
|
| - if (!Traits::Is64Bit)
|
| - split64(Dest);
|
| const SizeT MaxSrcs = 1;
|
| Type DestType = Dest->getType();
|
| Type SrcType = Inst->getSrc(0)->getType();
|
| @@ -2901,23 +2856,25 @@ void TargetX86Base<Machine>::lowerIntrinsicCall(
|
| return;
|
| }
|
| Variable *Dest = Instr->getDest();
|
| - if (!Traits::Is64Bit && Dest->getType() == IceType_i64) {
|
| - // Follow what GCC does and use a movq instead of what lowerLoad()
|
| - // normally does (split the load into two). Thus, this skips
|
| - // load/arithmetic op folding. Load/arithmetic folding can't happen
|
| - // anyway, since this is x86-32 and integer arithmetic only happens on
|
| - // 32-bit quantities.
|
| - Variable *T = makeReg(IceType_f64);
|
| - typename Traits::X86OperandMem *Addr =
|
| - formMemoryOperand(Instr->getArg(0), IceType_f64);
|
| - _movq(T, Addr);
|
| - // Then cast the bits back out of the XMM register to the i64 Dest.
|
| - InstCast *Cast = InstCast::create(Func, InstCast::Bitcast, Dest, T);
|
| - lowerCast(Cast);
|
| - // Make sure that the atomic load isn't elided when unused.
|
| - Context.insert(InstFakeUse::create(Func, Dest->getLo()));
|
| - Context.insert(InstFakeUse::create(Func, Dest->getHi()));
|
| - return;
|
| + if (!Traits::Is64Bit) {
|
| + if (auto *Dest64On32 = llvm::dyn_cast<Variable64On32>(Dest)) {
|
| + // Follow what GCC does and use a movq instead of what lowerLoad()
|
| + // normally does (split the load into two). Thus, this skips
|
| + // load/arithmetic op folding. Load/arithmetic folding can't happen
|
| + // anyway, since this is x86-32 and integer arithmetic only happens on
|
| + // 32-bit quantities.
|
| + Variable *T = makeReg(IceType_f64);
|
| + typename Traits::X86OperandMem *Addr =
|
| + formMemoryOperand(Instr->getArg(0), IceType_f64);
|
| + _movq(T, Addr);
|
| + // Then cast the bits back out of the XMM register to the i64 Dest.
|
| + InstCast *Cast = InstCast::create(Func, InstCast::Bitcast, Dest, T);
|
| + lowerCast(Cast);
|
| + // Make sure that the atomic load isn't elided when unused.
|
| + Context.insert(InstFakeUse::create(Func, Dest64On32->getLo()));
|
| + Context.insert(InstFakeUse::create(Func, Dest64On32->getHi()));
|
| + return;
|
| + }
|
| }
|
| InstLoad *Load = InstLoad::create(Func, Dest, Instr->getArg(0));
|
| lowerLoad(Load);
|
|
|