| Index: src/IceTargetLoweringX8632.cpp
|
| diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
|
| index 3808ecbb85cabb7ed570f2c82a6d8cabf93d07a6..112b8cb8e774e4584c4c01afa1fc4789cb418832 100644
|
| --- a/src/IceTargetLoweringX8632.cpp
|
| +++ b/src/IceTargetLoweringX8632.cpp
|
| @@ -3292,11 +3292,46 @@ void TargetX8632::lowerRet(const InstRet *Inst) {
|
| }
|
|
|
| void TargetX8632::lowerSelect(const InstSelect *Inst) {
|
| - // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1:
|
| Variable *Dest = Inst->getDest();
|
| Operand *SrcT = Inst->getTrueOperand();
|
| Operand *SrcF = Inst->getFalseOperand();
|
| - Operand *Condition = legalize(Inst->getCondition());
|
| + Operand *Condition = Inst->getCondition();
|
| +
|
| + if (isVectorType(Dest->getType())) {
|
| + // a=d?b:c ==> d=sext(d); a=(b&d)|(c&~d)
|
| + // TODO(wala): SSE4.1 has blendvps and pblendvb. SSE4.1 also has
|
| + // blendps and pblendw for constant condition operands.
|
| + Type SrcTy = SrcT->getType();
|
| + Variable *T = makeReg(SrcTy);
|
| + Variable *T2 = makeReg(SrcTy);
|
| + // Sign extend the condition operand if applicable.
|
| + if (SrcTy == IceType_v4f32) {
|
| + // The sext operation takes only integer arguments.
|
| + Variable *T3 = Func->makeVariable(IceType_v4i32, Context.getNode());
|
| + lowerCast(InstCast::create(Func, InstCast::Sext, T3, Condition));
|
| + _movp(T, T3);
|
| + } else if (typeElementType(SrcTy) != IceType_i1) {
|
| + lowerCast(InstCast::create(Func, InstCast::Sext, T, Condition));
|
| + } else {
|
| + _movp(T, Condition);
|
| + }
|
| + // ALIGNHACK: Until stack alignment support is implemented, the
|
| + // bitwise vector instructions need to have both operands in
|
| + // registers. Once there is support for stack alignment, LEGAL_HACK
|
| + // can be removed.
|
| +#define LEGAL_HACK(Vect) legalizeToVar((Vect))
|
| + _movp(T2, T);
|
| + _pand(T, LEGAL_HACK(SrcT));
|
| + _pandn(T2, LEGAL_HACK(SrcF));
|
| + _por(T, T2);
|
| + _movp(Dest, T);
|
| +#undef LEGAL_HACK
|
| +
|
| + return;
|
| + }
|
| +
|
| + // a=d?b:c ==> cmp d,0; a=b; jne L1; FakeUse(a); a=c; L1:
|
| + Operand *ConditionRMI = legalize(Condition);
|
| Constant *Zero = Ctx->getConstantZero(IceType_i32);
|
| InstX8632Label *Label = InstX8632Label::create(Func, this);
|
|
|
| @@ -3305,7 +3340,7 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) {
|
| Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
|
| Operand *SrcLoRI = legalize(loOperand(SrcT), Legal_Reg | Legal_Imm, true);
|
| Operand *SrcHiRI = legalize(hiOperand(SrcT), Legal_Reg | Legal_Imm, true);
|
| - _cmp(Condition, Zero);
|
| + _cmp(ConditionRMI, Zero);
|
| _mov(DestLo, SrcLoRI);
|
| _mov(DestHi, SrcHiRI);
|
| _br(InstX8632Br::Br_ne, Label);
|
| @@ -3318,7 +3353,7 @@ void TargetX8632::lowerSelect(const InstSelect *Inst) {
|
| _mov(DestLo, SrcLoRI);
|
| _mov(DestHi, SrcHiRI);
|
| } else {
|
| - _cmp(Condition, Zero);
|
| + _cmp(ConditionRMI, Zero);
|
| SrcT = legalize(SrcT, Legal_Reg | Legal_Imm, true);
|
| _mov(Dest, SrcT);
|
| _br(InstX8632Br::Br_ne, Label);
|
|
|