| Index: src/IceTargetLoweringX8632.cpp
|
| diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
|
| index 449e41378df44a6f5a0e5c23fd4fc5fc8d903966..af7b866d3696aa7a8a6c501cb3de738f208f4805 100644
|
| --- a/src/IceTargetLoweringX8632.cpp
|
| +++ b/src/IceTargetLoweringX8632.cpp
|
| @@ -1376,18 +1376,18 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| // a = cast(b) ==> t=cast(b); a=t; (link t->b, link a->t, no overlap)
|
| InstCast::OpKind CastKind = Inst->getCastKind();
|
| Variable *Dest = Inst->getDest();
|
| - // Src0RM is the source operand legalized to physical register or memory, but
|
| - // not immediate, since the relevant x86 native instructions don't allow an
|
| - // immediate operand. If the operand is an immediate, we could consider
|
| - // computing the strength-reduced result at translation time, but we're
|
| - // unlikely to see something like that in the bitcode that the optimizer
|
| - // wouldn't have already taken care of.
|
| - Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
|
| switch (CastKind) {
|
| default:
|
| Func->setError("Cast type not supported");
|
| return;
|
| - case InstCast::Sext:
|
| + case InstCast::Sext: {
|
| + // Src0RM is the source operand legalized to physical register or memory,
|
| + // but not immediate, since the relevant x86 native instructions don't
|
| + // allow an immediate operand. If the operand is an immediate, we could
|
| + // consider computing the strength-reduced result at translation time,
|
| + // but we're unlikely to see something like that in the bitcode that
|
| + // the optimizer wouldn't have already taken care of.
|
| + Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
|
| if (Dest->getType() == IceType_i64) {
|
| // t1=movsx src; t2=t1; t2=sar t2, 31; dst.lo=t1; dst.hi=t2
|
| Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
|
| @@ -1412,7 +1412,9 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| _mov(Dest, T);
|
| }
|
| break;
|
| - case InstCast::Zext:
|
| + }
|
| + case InstCast::Zext: {
|
| + Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
|
| if (Dest->getType() == IceType_i64) {
|
| // t1=movzx src; dst.lo=t1; dst.hi=0
|
| Constant *Zero = Ctx->getConstantZero(IceType_i32);
|
| @@ -1439,9 +1441,12 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| _mov(Dest, T);
|
| }
|
| break;
|
| + }
|
| case InstCast::Trunc: {
|
| - if (Src0RM->getType() == IceType_i64)
|
| - Src0RM = loOperand(Src0RM);
|
| + Operand *Src0 = Inst->getSrc(0);
|
| + if (Src0->getType() == IceType_i64)
|
| + Src0 = loOperand(Src0);
|
| + Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
|
| // t1 = trunc Src0RM; Dest = t1
|
| Variable *T = NULL;
|
| _mov(T, Src0RM);
|
| @@ -1450,6 +1455,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| }
|
| case InstCast::Fptrunc:
|
| case InstCast::Fpext: {
|
| + Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
|
| // t1 = cvt Src0RM; Dest = t1
|
| Variable *T = makeReg(Dest->getType());
|
| _cvt(T, Src0RM);
|
| @@ -1473,6 +1479,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| Call->addArg(Inst->getSrc(0));
|
| lowerCall(Call);
|
| } else {
|
| + Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
|
| // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
|
| Variable *T_1 = makeReg(IceType_i32);
|
| Variable *T_2 = makeReg(Dest->getType());
|
| @@ -1488,7 +1495,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| split64(Dest);
|
| const SizeT MaxSrcs = 1;
|
| Type DestType = Dest->getType();
|
| - Type SrcType = Src0RM->getType();
|
| + Type SrcType = Inst->getSrc(0)->getType();
|
| IceString DstSubstring = (DestType == IceType_i64 ? "64" : "32");
|
| IceString SrcSubstring = (SrcType == IceType_f32 ? "f" : "d");
|
| // Possibilities are cvtftoui32, cvtdtoui32, cvtftoui64, cvtdtoui64
|
| @@ -1499,6 +1506,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| lowerCall(Call);
|
| return;
|
| } else {
|
| + Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
|
| // t1.i32 = cvt Src0RM; t2.dest_type = t1; Dest = t2.dest_type
|
| Variable *T_1 = makeReg(IceType_i32);
|
| Variable *T_2 = makeReg(Dest->getType());
|
| @@ -1509,7 +1517,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| }
|
| break;
|
| case InstCast::Sitofp:
|
| - if (Src0RM->getType() == IceType_i64) {
|
| + if (Inst->getSrc(0)->getType() == IceType_i64) {
|
| // Use a helper for x86-32.
|
| const SizeT MaxSrcs = 1;
|
| Type DestType = Dest->getType();
|
| @@ -1520,6 +1528,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| lowerCall(Call);
|
| return;
|
| } else {
|
| + Operand *Src0RM = legalize(Inst->getSrc(0), Legal_Reg | Legal_Mem);
|
| // Sign-extend the operand.
|
| // t1.i32 = movsx Src0RM; t2 = Cvt t1.i32; Dest = t2
|
| Variable *T_1 = makeReg(IceType_i32);
|
| @@ -1532,22 +1541,24 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| _mov(Dest, T_2);
|
| }
|
| break;
|
| - case InstCast::Uitofp:
|
| - if (Src0RM->getType() == IceType_i64 || Src0RM->getType() == IceType_i32) {
|
| + case InstCast::Uitofp: {
|
| + Operand *Src0 = Inst->getSrc(0);
|
| + if (Src0->getType() == IceType_i64 || Src0->getType() == IceType_i32) {
|
| // Use a helper for x86-32 and x86-64. Also use a helper for
|
| // i32 on x86-32.
|
| const SizeT MaxSrcs = 1;
|
| Type DestType = Dest->getType();
|
| - IceString SrcSubstring = (Src0RM->getType() == IceType_i64 ? "64" : "32");
|
| + IceString SrcSubstring = (Src0->getType() == IceType_i64 ? "64" : "32");
|
| IceString DstSubstring = (DestType == IceType_f32 ? "f" : "d");
|
| // Possibilities are cvtui32tof, cvtui32tod, cvtui64tof, cvtui64tod
|
| IceString TargetString = "cvtui" + SrcSubstring + "to" + DstSubstring;
|
| // TODO: Call the correct compiler-rt helper function.
|
| InstCall *Call = makeHelperCall(TargetString, Dest, MaxSrcs);
|
| - Call->addArg(Inst->getSrc(0));
|
| + Call->addArg(Src0);
|
| lowerCall(Call);
|
| return;
|
| } else {
|
| + Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
|
| // Zero-extend the operand.
|
| // t1.i32 = movzx Src0RM; t2 = Cvt t1.i32; Dest = t2
|
| Variable *T_1 = makeReg(IceType_i32);
|
| @@ -1560,9 +1571,11 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| _mov(Dest, T_2);
|
| }
|
| break;
|
| - case InstCast::Bitcast:
|
| - if (Dest->getType() == Src0RM->getType()) {
|
| - InstAssign *Assign = InstAssign::create(Func, Dest, Src0RM);
|
| + }
|
| + case InstCast::Bitcast: {
|
| + Operand *Src0 = Inst->getSrc(0);
|
| + if (Dest->getType() == Src0->getType()) {
|
| + InstAssign *Assign = InstAssign::create(Func, Dest, Src0);
|
| lowerAssign(Assign);
|
| return;
|
| }
|
| @@ -1571,6 +1584,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| llvm_unreachable("Unexpected Bitcast dest type");
|
| case IceType_i32:
|
| case IceType_f32: {
|
| + Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
|
| Type DestType = Dest->getType();
|
| Type SrcType = Src0RM->getType();
|
| assert((DestType == IceType_i32 && SrcType == IceType_f32) ||
|
| @@ -1590,6 +1604,7 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| _mov(Dest, Spill);
|
| } break;
|
| case IceType_i64: {
|
| + Operand *Src0RM = legalize(Src0, Legal_Reg | Legal_Mem);
|
| assert(Src0RM->getType() == IceType_f64);
|
| // a.i64 = bitcast b.f64 ==>
|
| // s.f64 = spill b.f64
|
| @@ -1617,11 +1632,12 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| _mov(DestHi, T_Hi);
|
| } break;
|
| case IceType_f64: {
|
| - assert(Src0RM->getType() == IceType_i64);
|
| + Src0 = legalize(Src0);
|
| + assert(Src0->getType() == IceType_i64);
|
| // a.f64 = bitcast b.i64 ==>
|
| // t_lo.i32 = b_lo.i32
|
| + // FakeDef(s.f64)
|
| // lo(s.f64) = t_lo.i32
|
| - // FakeUse(s.f64)
|
| // t_hi.i32 = b_hi.i32
|
| // hi(s.f64) = t_hi.i32
|
| // a.f64 = s.f64
|
| @@ -1629,22 +1645,25 @@ void TargetX8632::lowerCast(const InstCast *Inst) {
|
| Spill->setWeight(RegWeight::Zero);
|
| Spill->setPreferredRegister(Dest, true);
|
|
|
| - Context.insert(InstFakeDef::create(Func, Spill));
|
| -
|
| Variable *T_Lo = NULL, *T_Hi = NULL;
|
| VariableSplit *SpillLo =
|
| VariableSplit::create(Func, Spill, VariableSplit::Low);
|
| VariableSplit *SpillHi =
|
| VariableSplit::create(Func, Spill, VariableSplit::High);
|
| - _mov(T_Lo, loOperand(Src0RM));
|
| + _mov(T_Lo, loOperand(Src0));
|
| + // Technically, the Spill is defined after the _store happens, but
|
| + // SpillLo is considered a "use" of Spill so define Spill before it
|
| + // is used.
|
| + Context.insert(InstFakeDef::create(Func, Spill));
|
| _store(T_Lo, SpillLo);
|
| - _mov(T_Hi, hiOperand(Src0RM));
|
| + _mov(T_Hi, hiOperand(Src0));
|
| _store(T_Hi, SpillHi);
|
| _mov(Dest, Spill);
|
| } break;
|
| }
|
| break;
|
| }
|
| + }
|
| }
|
|
|
| void TargetX8632::lowerFcmp(const InstFcmp *Inst) {
|
| @@ -2312,6 +2331,8 @@ Variable *TargetX8632::legalizeToVar(Operand *From, bool AllowOverlap,
|
| }
|
|
|
| Variable *TargetX8632::makeReg(Type Type, int32_t RegNum) {
|
| + // There aren't any 64-bit integer registers for x86-32.
|
| + assert(Type != IceType_i64);
|
| Variable *Reg = Func->makeVariable(Type, Context.getNode());
|
| if (RegNum == Variable::NoRegister)
|
| Reg->setWeightInfinite();
|
|
|