Chromium Code Reviews| Index: src/IceTargetLoweringX86BaseImpl.h |
| diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h |
| index 56ee04d32e6510add168fd47871608b65c2cc9e2..6a3c0f50166e39342f59e3b05c3b289c34bda204 100644 |
| --- a/src/IceTargetLoweringX86BaseImpl.h |
| +++ b/src/IceTargetLoweringX86BaseImpl.h |
| @@ -81,7 +81,8 @@ public: |
| PK_Icmp32, |
| PK_Icmp64, |
| PK_Fcmp, |
| - PK_Trunc |
| + PK_Trunc, |
| + PK_Arith // A flag-setting arithmetic instruction. |
| }; |
| /// Currently the actual enum values are not used (other than CK_None), but we |
| @@ -125,10 +126,21 @@ BoolFolding<MachineTraits>::getProducerKind(const Inst *Instr) { |
| return PK_Icmp32; |
| return PK_Icmp64; |
| } |
| - return PK_None; // TODO(stichnot): remove this |
| - |
| if (llvm::isa<InstFcmp>(Instr)) |
| return PK_Fcmp; |
| + if (auto *Arith = llvm::dyn_cast<InstArithmetic>(Instr)) { |
| + if (MachineTraits::Is64Bit || Arith->getSrc(0)->getType() != IceType_i64) { |
| + switch (Arith->getOp()) { |
| + default: |
| + break; |
|
Jim Stichnoth
2015/11/11 14:05:20
I think you should just "return PK_None", unless y
sehr
2015/11/13 06:00:52
Done.
|
| + case InstArithmetic::And: |
| + case InstArithmetic::Or: |
| + return PK_Arith; |
| + } |
| + } |
| + } |
| + return PK_None; // TODO(stichnot): remove this |
| + |
| if (auto *Cast = llvm::dyn_cast<InstCast>(Instr)) { |
| switch (Cast->getCastKind()) { |
| default: |
| @@ -1925,9 +1937,16 @@ void TargetX86Base<Machine>::lowerBr(const InstBr *Inst) { |
| lowerIcmpAndBr(llvm::dyn_cast<InstIcmp>(Producer), Inst); |
| return; |
| } |
| + case BoolFolding::PK_Fcmp: { |
| + lowerFcmpAndBr(llvm::dyn_cast<InstFcmp>(Producer), Inst); |
| + return; |
| + } |
| + case BoolFolding::PK_Arith: { |
| + lowerArithAndBr(llvm::dyn_cast<InstArithmetic>(Producer), Inst); |
| + return; |
| + } |
| } |
| } |
| - |
| Operand *Src0 = legalize(Cond, Legal_Reg | Legal_Mem); |
| Constant *Zero = Ctx->getConstantZero(IceType_i32); |
| _cmp(Src0, Zero); |
| @@ -2540,11 +2559,20 @@ void TargetX86Base<Machine>::lowerExtractElement( |
| template <class Machine> |
| void TargetX86Base<Machine>::lowerFcmp(const InstFcmp *Inst) { |
| + constexpr InstBr *Br = nullptr; |
| + lowerFcmpAndBr(Inst, Br); |
| +} |
| + |
| +template <class Machine> |
| +void TargetX86Base<Machine>::lowerFcmpAndBr(const InstFcmp *Inst, |
| + const InstBr *Br) { |
| Operand *Src0 = Inst->getSrc(0); |
| Operand *Src1 = Inst->getSrc(1); |
| Variable *Dest = Inst->getDest(); |
| if (isVectorType(Dest->getType())) { |
| + if (Br) |
| + llvm::report_fatal_error("vector compare/branch cannot be folded"); |
| InstFcmp::FCond Condition = Inst->getCondition(); |
| size_t Index = static_cast<size_t>(Condition); |
| assert(Index < Traits::TableFcmpSize); |
| @@ -2633,24 +2661,47 @@ void TargetX86Base<Machine>::lowerFcmp(const InstFcmp *Inst) { |
| _ucomiss(T, Src1RM); |
| if (!HasC2) { |
| assert(Traits::TableFcmp[Index].Default); |
| - _setcc(Dest, Traits::TableFcmp[Index].C1); |
| + setccOrBr(Traits::TableFcmp[Index].C1, Dest, Br); |
| return; |
| } |
| } |
| - Constant *Default = |
| - Ctx->getConstantInt(Dest->getType(), Traits::TableFcmp[Index].Default); |
| - _mov(Dest, Default); |
| - if (HasC1) { |
| - typename Traits::Insts::Label *Label = |
| - Traits::Insts::Label::create(Func, this); |
| - _br(Traits::TableFcmp[Index].C1, Label); |
| - if (HasC2) { |
| - _br(Traits::TableFcmp[Index].C2, Label); |
| + int32_t IntDefault = Traits::TableFcmp[Index].Default; |
| + if (Br == nullptr) { |
| + Constant *Default = Ctx->getConstantInt(Dest->getType(), IntDefault); |
| + _mov(Dest, Default); |
| + if (HasC1) { |
| + typename Traits::Insts::Label *Label = |
| + Traits::Insts::Label::create(Func, this); |
| + _br(Traits::TableFcmp[Index].C1, Label); |
| + if (HasC2) { |
| + _br(Traits::TableFcmp[Index].C2, Label); |
| + } |
| + Constant *NonDefault = Ctx->getConstantInt(Dest->getType(), !IntDefault); |
| + _mov_redefined(Dest, NonDefault); |
| + Context.insert(Label); |
| + } |
| + } else { |
|
Jim Stichnoth
2015/11/11 14:05:20
Can this be "else if"?
} else if (IntDefault ==
sehr
2015/11/13 06:00:52
I used std::swap and removed the duplication, as w
|
| + if (IntDefault == 0) { |
| + if (HasC1) { |
| + _br(Traits::TableFcmp[Index].C1, Br->getTargetFalse()); |
| + if (HasC2) { |
| + _br(Traits::TableFcmp[Index].C2, Br->getTargetFalse()); |
| + } |
| + _br(Br->getTargetTrue()); |
| + return; |
| + } |
| + _br(Br->getTargetFalse()); |
| + } else { |
| + if (HasC1) { |
| + _br(Traits::TableFcmp[Index].C1, Br->getTargetTrue()); |
| + if (HasC2) { |
| + _br(Traits::TableFcmp[Index].C2, Br->getTargetTrue()); |
| + } |
| + _br(Br->getTargetFalse()); |
| + return; |
| + } |
| + _br(Br->getTargetTrue()); |
| } |
| - Constant *NonDefault = |
| - Ctx->getConstantInt(Dest->getType(), !Traits::TableFcmp[Index].Default); |
| - _mov_redefined(Dest, NonDefault); |
| - Context.insert(Label); |
| } |
| } |
| @@ -2960,6 +3011,31 @@ void TargetX86Base<Machine>::movOrBr(bool IcmpResult, Variable *Dest, |
| } |
| template <class Machine> |
| +void TargetX86Base<Machine>::lowerArithAndBr(const InstArithmetic *Arith, |
| + const InstBr *Br) { |
| + Variable *T = nullptr; |
| + Operand *Src0 = legalize(Arith->getSrc(0)); |
| + Operand *Src1 = legalize(Arith->getSrc(1)); |
| + Variable *Dest = Arith->getDest(); |
| + switch (Arith->getOp()) { |
| + default: |
| + llvm_unreachable("arithmetic operator not AND or OR"); |
| + break; |
| + case InstArithmetic::And: |
| + _mov(T, Src0); |
| + _and(T, Src1); |
|
John
2015/11/11 02:08:10
would _test be better here? just curious.
Jim Stichnoth
2015/11/11 14:05:20
Yes it would be better, since T would be able to s
sehr
2015/11/13 06:00:52
Done.
sehr
2015/11/13 06:00:52
Done.
|
| + break; |
| + case InstArithmetic::Or: |
| + _mov(T, Src0); |
| + _or(T, Src1); |
| + break; |
| + } |
| + Context.insert(InstFakeUse::create(Func, T)); |
| + Context.insert(InstFakeDef::create(Func, Dest)); |
| + _br(Traits::Cond::Br_ne, Br->getTargetTrue(), Br->getTargetFalse()); |
| +} |
| + |
| +template <class Machine> |
| void TargetX86Base<Machine>::lowerInsertElement(const InstInsertElement *Inst) { |
| Operand *SourceVectNotLegalized = Inst->getSrc(0); |
| Operand *ElementToInsertNotLegalized = Inst->getSrc(1); |