| Index: src/IceTargetLoweringX8632.cpp
|
| diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
|
| index 0aaafa2f7db8add2195fc63104870d81f644aa01..478a6b6ba58deed4720fe2b88d4383dadf913951 100644
|
| --- a/src/IceTargetLoweringX8632.cpp
|
| +++ b/src/IceTargetLoweringX8632.cpp
|
| @@ -4076,11 +4076,12 @@ void TargetX8632::lowerRet(const InstRet *Inst) {
|
|
|
| void TargetX8632::lowerSelect(const InstSelect *Inst) {
|
| Variable *Dest = Inst->getDest();
|
| + Type DestTy = Dest->getType();
|
| Operand *SrcT = Inst->getTrueOperand();
|
| Operand *SrcF = Inst->getFalseOperand();
|
| Operand *Condition = Inst->getCondition();
|
|
|
| - if (isVectorType(Dest->getType())) {
|
| + if (isVectorType(DestTy)) {
|
| Type SrcTy = SrcT->getType();
|
| Variable *T = makeReg(SrcTy);
|
| Operand *SrcTRM = legalize(SrcT, Legal_Reg | Legal_Mem);
|
| @@ -4138,6 +4139,9 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) {
|
| return;
|
| }
|
|
|
| + CondX86::BrCond Cond = CondX86::Br_ne;
|
| + Operand *CmpOpnd0 = nullptr;
|
| + Operand *CmpOpnd1 = nullptr;
|
| // Handle folding opportunities.
|
| if (const class Inst *Producer = FoldingInfo.getProducerFor(Condition)) {
|
| assert(Producer->isDeleted());
|
| @@ -4145,73 +4149,69 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) {
|
| default:
|
| break;
|
| case BoolFolding::PK_Icmp32: {
|
| - // d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1:
|
| auto *Cmp = llvm::dyn_cast<InstIcmp>(Producer);
|
| - InstX8632Label *Label = InstX8632Label::create(Func, this);
|
| - Operand *Src0 = Producer->getSrc(0);
|
| - Operand *Src1 = legalize(Producer->getSrc(1));
|
| - Operand *Src0RM = legalizeSrc0ForCmp(Src0, Src1);
|
| - _cmp(Src0RM, Src1);
|
| - // This is the same code as below (for both i64 and non-i64),
|
| - // except without the _cmp instruction and with a different
|
| - // branch condition. TODO(stichnot): refactor.
|
| - if (Dest->getType() == IceType_i64) {
|
| - Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
|
| - Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
|
| - Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm);
|
| - Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm);
|
| - _mov(DestLo, SrcLoRI);
|
| - _mov(DestHi, SrcHiRI);
|
| - _br(getIcmp32Mapping(Cmp->getCondition()), Label);
|
| - Operand *SrcFLo = loOperand(SrcF);
|
| - Operand *SrcFHi = hiOperand(SrcF);
|
| - SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm);
|
| - SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm);
|
| - _mov_nonkillable(DestLo, SrcLoRI);
|
| - _mov_nonkillable(DestHi, SrcHiRI);
|
| - } else {
|
| - SrcT = legalize(SrcT, Legal_Reg | Legal_Imm);
|
| - _mov(Dest, SrcT);
|
| - _br(getIcmp32Mapping(Cmp->getCondition()), Label);
|
| - SrcF = legalize(SrcF, Legal_Reg | Legal_Imm);
|
| - _mov_nonkillable(Dest, SrcF);
|
| - }
|
| - Context.insert(Label);
|
| - return;
|
| - }
|
| + Cond = getIcmp32Mapping(Cmp->getCondition());
|
| + CmpOpnd1 = legalize(Producer->getSrc(1));
|
| + CmpOpnd0 = legalizeSrc0ForCmp(Producer->getSrc(0), CmpOpnd1);
|
| + } break;
|
| }
|
| }
|
| + if (CmpOpnd0 == nullptr) {
|
| + CmpOpnd0 = legalize(Condition, Legal_Reg | Legal_Mem);
|
| + CmpOpnd1 = Ctx->getConstantZero(IceType_i32);
|
| + }
|
| + assert(CmpOpnd0);
|
| + assert(CmpOpnd1);
|
|
|
| - // a=d?b:c ==> cmp d,0; a=b; jne L1; a=c; L1:
|
| - Operand *ConditionRM = legalize(Condition, Legal_Reg | Legal_Mem);
|
| - Constant *Zero = Ctx->getConstantZero(IceType_i32);
|
| - InstX8632Label *Label = InstX8632Label::create(Func, this);
|
| -
|
| - if (Dest->getType() == IceType_i64) {
|
| - Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
|
| - Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
|
| - Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm);
|
| - Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm);
|
| - _cmp(ConditionRM, Zero);
|
| - _mov(DestLo, SrcLoRI);
|
| - _mov(DestHi, SrcHiRI);
|
| - _br(CondX86::Br_ne, Label);
|
| - Operand *SrcFLo = loOperand(SrcF);
|
| - Operand *SrcFHi = hiOperand(SrcF);
|
| - SrcLoRI = legalize(SrcFLo, Legal_Reg | Legal_Imm);
|
| - SrcHiRI = legalize(SrcFHi, Legal_Reg | Legal_Imm);
|
| - _mov_nonkillable(DestLo, SrcLoRI);
|
| - _mov_nonkillable(DestHi, SrcHiRI);
|
| - } else {
|
| - _cmp(ConditionRM, Zero);
|
| + _cmp(CmpOpnd0, CmpOpnd1);
|
| + if (typeWidthInBytes(DestTy) == 1 || isFloatingType(DestTy)) {
|
| + // The cmov instruction doesn't allow 8-bit or FP operands, so
|
| + // we need explicit control flow.
|
| + // d=cmp e,f; a=d?b:c ==> cmp e,f; a=b; jne L1; a=c; L1:
|
| + InstX8632Label *Label = InstX8632Label::create(Func, this);
|
| SrcT = legalize(SrcT, Legal_Reg | Legal_Imm);
|
| _mov(Dest, SrcT);
|
| - _br(CondX86::Br_ne, Label);
|
| + _br(Cond, Label);
|
| SrcF = legalize(SrcF, Legal_Reg | Legal_Imm);
|
| _mov_nonkillable(Dest, SrcF);
|
| + Context.insert(Label);
|
| + return;
|
| + }
|
| + // mov t, SrcF; cmov_cond t, SrcT; mov dest, t
|
| + // But if SrcT is immediate, we might be able to do better, as
|
| + // the cmov instruction doesn't allow an immediate operand:
|
| + // mov t, SrcT; cmov_!cond t, SrcF; mov dest, t
|
| + if (llvm::isa<Constant>(SrcT) && !llvm::isa<Constant>(SrcF)) {
|
| + std::swap(SrcT, SrcF);
|
| + Cond = InstX8632::getOppositeCondition(Cond);
|
| + }
|
| + if (DestTy == IceType_i64) {
|
| + // Set the low portion.
|
| + Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
|
| + Variable *TLo = nullptr;
|
| + Operand *SrcFLo = legalize(loOperand(SrcF));
|
| + _mov(TLo, SrcFLo);
|
| + Operand *SrcTLo = legalize(loOperand(SrcT), Legal_Reg | Legal_Mem);
|
| + _cmov(TLo, SrcTLo, Cond);
|
| + _mov(DestLo, TLo);
|
| + // Set the high portion.
|
| + Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
|
| + Variable *THi = nullptr;
|
| + Operand *SrcFHi = legalize(hiOperand(SrcF));
|
| + _mov(THi, SrcFHi);
|
| + Operand *SrcTHi = legalize(hiOperand(SrcT), Legal_Reg | Legal_Mem);
|
| + _cmov(THi, SrcTHi, Cond);
|
| + _mov(DestHi, THi);
|
| + return;
|
| }
|
|
|
| - Context.insert(Label);
|
| + assert(DestTy == IceType_i16 || DestTy == IceType_i32);
|
| + Variable *T = nullptr;
|
| + SrcF = legalize(SrcF);
|
| + _mov(T, SrcF);
|
| + SrcT = legalize(SrcT, Legal_Reg | Legal_Mem);
|
| + _cmov(T, SrcT, Cond);
|
| + _mov(Dest, T);
|
| }
|
|
|
| void TargetX8632::lowerStore(const InstStore *Inst) {
|
|
|