Index: src/IceTargetLoweringX8632.cpp |
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp |
index ba519e826fe53a626f5be6afe2228e0be29c9f3c..94ab396ccaffdbb52390180d8791bbab315095ab 100644 |
--- a/src/IceTargetLoweringX8632.cpp |
+++ b/src/IceTargetLoweringX8632.cpp |
@@ -587,32 +587,31 @@ namespace { |
bool canRMW(const InstArithmetic *Arith) { |
Type Ty = Arith->getDest()->getType(); |
+ // X86 vector instructions write to a register and have no RMW |
+ // option. |
+ if (isVectorType(Ty)) |
+ return false; |
bool isI64 = Ty == IceType_i64; |
- bool isVector = isVectorType(Ty); |
switch (Arith->getOp()) { |
// Not handled for lack of simple lowering: |
- // shift on i64 and vectors |
+ // shift on i64 |
// mul, udiv, urem, sdiv, srem, frem |
+ // Not handled for lack of RMW instructions: |
+ // fadd, fsub, fmul, fdiv (also vector types) |
default: |
return false; |
case InstArithmetic::Add: |
- return !isI64 && !isVector; // TODO(stichnot): implement i64 and vector |
case InstArithmetic::Sub: |
case InstArithmetic::And: |
case InstArithmetic::Or: |
case InstArithmetic::Xor: |
- case InstArithmetic::Fadd: |
- case InstArithmetic::Fsub: |
- case InstArithmetic::Fmul: |
- case InstArithmetic::Fdiv: |
- return false; // TODO(stichnot): implement |
return true; |
case InstArithmetic::Shl: |
case InstArithmetic::Lshr: |
case InstArithmetic::Ashr: |
return false; // TODO(stichnot): implement |
- return !isI64 && !isVector; |
+ return !isI64; |
} |
} |
@@ -3442,10 +3441,11 @@ void TargetX8632::lowerIntrinsicCall(const InstIntrinsicCall *Instr) { |
Func->setError("Unexpected memory ordering for AtomicRMW"); |
return; |
} |
- lowerAtomicRMW(Instr->getDest(), |
- static_cast<uint32_t>(llvm::cast<ConstantInteger32>( |
- Instr->getArg(0))->getValue()), |
- Instr->getArg(1), Instr->getArg(2)); |
+ lowerAtomicRMW( |
+ Instr->getDest(), |
+ static_cast<uint32_t>( |
+ llvm::cast<ConstantInteger32>(Instr->getArg(0))->getValue()), |
+ Instr->getArg(1), Instr->getArg(2)); |
return; |
case Intrinsics::AtomicStore: { |
if (!Intrinsics::isMemoryOrderValid( |
@@ -4660,11 +4660,37 @@ void TargetX8632::lowerRMW(const InstX8632FakeRMW *RMW) { |
Type Ty = Src->getType(); |
OperandX8632Mem *Addr = formMemoryOperand(RMW->getAddr(), Ty); |
if (Ty == IceType_i64) { |
- // TODO(stichnot): Implement. |
- } else if (isVectorType(Ty)) { |
- // TODO(stichnot): Implement. |
+ Operand *SrcLo = legalize(loOperand(Src), Legal_Reg | Legal_Imm); |
+ Operand *SrcHi = legalize(hiOperand(Src), Legal_Reg | Legal_Imm); |
+ OperandX8632Mem *AddrLo = llvm::cast<OperandX8632Mem>(loOperand(Addr)); |
+ OperandX8632Mem *AddrHi = llvm::cast<OperandX8632Mem>(hiOperand(Addr)); |
+ switch (RMW->getOp()) { |
+ default: |
+ // TODO(stichnot): Implement other arithmetic operators. |
+ break; |
+ case InstArithmetic::Add: |
+ _add_rmw(AddrLo, SrcLo); |
+ _adc_rmw(AddrHi, SrcHi); |
+ return; |
+ case InstArithmetic::Sub: |
+ _sub_rmw(AddrLo, SrcLo); |
+ _sbb_rmw(AddrHi, SrcHi); |
+ return; |
+ case InstArithmetic::And: |
+ _and_rmw(AddrLo, SrcLo); |
+ _and_rmw(AddrHi, SrcHi); |
+ return; |
+ case InstArithmetic::Or: |
+ _or_rmw(AddrLo, SrcLo); |
+ _or_rmw(AddrHi, SrcHi); |
+ return; |
+ case InstArithmetic::Xor: |
+ _xor_rmw(AddrLo, SrcLo); |
+ _xor_rmw(AddrHi, SrcHi); |
+ return; |
+ } |
} else { |
- // i8, i16, i32, f32, f64 |
+ // i8, i16, i32 |
switch (RMW->getOp()) { |
default: |
// TODO(stichnot): Implement other arithmetic operators. |
@@ -4673,6 +4699,22 @@ void TargetX8632::lowerRMW(const InstX8632FakeRMW *RMW) { |
Src = legalize(Src, Legal_Reg | Legal_Imm); |
_add_rmw(Addr, Src); |
return; |
+ case InstArithmetic::Sub: |
+ Src = legalize(Src, Legal_Reg | Legal_Imm); |
+ _sub_rmw(Addr, Src); |
+ return; |
+ case InstArithmetic::And: |
+ Src = legalize(Src, Legal_Reg | Legal_Imm); |
+ _and_rmw(Addr, Src); |
+ return; |
+ case InstArithmetic::Or: |
+ Src = legalize(Src, Legal_Reg | Legal_Imm); |
+ _or_rmw(Addr, Src); |
+ return; |
+ case InstArithmetic::Xor: |
+ Src = legalize(Src, Legal_Reg | Legal_Imm); |
+ _xor_rmw(Addr, Src); |
+ return; |
} |
} |
llvm::report_fatal_error("Couldn't lower RMW instruction"); |