mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 22:30:33 +00:00
Add missing i64 max/min/umax/umin on 32-bit target
- Turn on atomic6432.ll and add specific test case as well llvm-svn: 164616
This commit is contained in:
parent
97e019d375
commit
b50e89ddce
@ -2040,6 +2040,10 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
|
||||
case X86ISD::ATOMSUB64_DAG:
|
||||
case X86ISD::ATOMNAND64_DAG:
|
||||
case X86ISD::ATOMAND64_DAG:
|
||||
case X86ISD::ATOMMAX64_DAG:
|
||||
case X86ISD::ATOMMIN64_DAG:
|
||||
case X86ISD::ATOMUMAX64_DAG:
|
||||
case X86ISD::ATOMUMIN64_DAG:
|
||||
case X86ISD::ATOMSWAP64_DAG: {
|
||||
unsigned Opc;
|
||||
switch (Opcode) {
|
||||
@ -2050,6 +2054,10 @@ SDNode *X86DAGToDAGISel::Select(SDNode *Node) {
|
||||
case X86ISD::ATOMSUB64_DAG: Opc = X86::ATOMSUB6432; break;
|
||||
case X86ISD::ATOMNAND64_DAG: Opc = X86::ATOMNAND6432; break;
|
||||
case X86ISD::ATOMAND64_DAG: Opc = X86::ATOMAND6432; break;
|
||||
case X86ISD::ATOMMAX64_DAG: Opc = X86::ATOMMAX6432; break;
|
||||
case X86ISD::ATOMMIN64_DAG: Opc = X86::ATOMMIN6432; break;
|
||||
case X86ISD::ATOMUMAX64_DAG: Opc = X86::ATOMUMAX6432; break;
|
||||
case X86ISD::ATOMUMIN64_DAG: Opc = X86::ATOMUMIN6432; break;
|
||||
case X86ISD::ATOMSWAP64_DAG: Opc = X86::ATOMSWAP6432; break;
|
||||
}
|
||||
SDNode *RetVal = SelectAtomic64(Node, Opc);
|
||||
|
@ -514,6 +514,10 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
|
||||
setOperationAction(ISD::ATOMIC_LOAD_XOR, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ATOMIC_LOAD_NAND, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ATOMIC_SWAP, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ATOMIC_LOAD_MAX, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ATOMIC_LOAD_MIN, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ATOMIC_LOAD_UMAX, MVT::i64, Custom);
|
||||
setOperationAction(ISD::ATOMIC_LOAD_UMIN, MVT::i64, Custom);
|
||||
}
|
||||
|
||||
if (Subtarget->hasCmpxchg16b()) {
|
||||
@ -11593,6 +11597,10 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
|
||||
case ISD::ATOMIC_LOAD_OR:
|
||||
case ISD::ATOMIC_LOAD_SUB:
|
||||
case ISD::ATOMIC_LOAD_XOR:
|
||||
case ISD::ATOMIC_LOAD_MAX:
|
||||
case ISD::ATOMIC_LOAD_MIN:
|
||||
case ISD::ATOMIC_LOAD_UMAX:
|
||||
case ISD::ATOMIC_LOAD_UMIN:
|
||||
case ISD::ATOMIC_SWAP: {
|
||||
unsigned Opc;
|
||||
switch (N->getOpcode()) {
|
||||
@ -11615,6 +11623,18 @@ void X86TargetLowering::ReplaceNodeResults(SDNode *N,
|
||||
case ISD::ATOMIC_LOAD_XOR:
|
||||
Opc = X86ISD::ATOMXOR64_DAG;
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_MAX:
|
||||
Opc = X86ISD::ATOMMAX64_DAG;
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_MIN:
|
||||
Opc = X86ISD::ATOMMIN64_DAG;
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_UMAX:
|
||||
Opc = X86ISD::ATOMUMAX64_DAG;
|
||||
break;
|
||||
case ISD::ATOMIC_LOAD_UMIN:
|
||||
Opc = X86ISD::ATOMUMIN64_DAG;
|
||||
break;
|
||||
case ISD::ATOMIC_SWAP:
|
||||
Opc = X86ISD::ATOMSWAP64_DAG;
|
||||
break;
|
||||
@ -12004,6 +12024,10 @@ static unsigned getNonAtomic6432Opcode(unsigned Opc, unsigned &HiOpc) {
|
||||
case X86::ATOMADD6432: HiOpc = X86::ADC32rr; return X86::ADD32rr;
|
||||
case X86::ATOMSUB6432: HiOpc = X86::SBB32rr; return X86::SUB32rr;
|
||||
case X86::ATOMSWAP6432: HiOpc = X86::MOV32rr; return X86::MOV32rr;
|
||||
case X86::ATOMMAX6432: HiOpc = X86::SETLr; return X86::SETLr;
|
||||
case X86::ATOMMIN6432: HiOpc = X86::SETGr; return X86::SETGr;
|
||||
case X86::ATOMUMAX6432: HiOpc = X86::SETBr; return X86::SETBr;
|
||||
case X86::ATOMUMIN6432: HiOpc = X86::SETAr; return X86::SETAr;
|
||||
}
|
||||
llvm_unreachable("Unhandled atomic-load-op opcode!");
|
||||
}
|
||||
@ -12321,6 +12345,7 @@ X86TargetLowering::EmitAtomicLoadArith6432(MachineInstr *MI,
|
||||
SrcHiReg = MI->getOperand(CurOp++).getReg();
|
||||
|
||||
const TargetRegisterClass *RC = &X86::GR32RegClass;
|
||||
const TargetRegisterClass *RC8 = &X86::GR8RegClass;
|
||||
|
||||
unsigned LCMPXCHGOpc = X86::LCMPXCHG8B;
|
||||
unsigned LOADOpc = X86::MOV32rm;
|
||||
@ -12408,6 +12433,55 @@ X86TargetLowering::EmitAtomicLoadArith6432(MachineInstr *MI,
|
||||
BuildMI(mainMBB, DL, TII->get(NOTOpc), t1H).addReg(t2H);
|
||||
break;
|
||||
}
|
||||
case X86::ATOMMAX6432:
|
||||
case X86::ATOMMIN6432:
|
||||
case X86::ATOMUMAX6432:
|
||||
case X86::ATOMUMIN6432: {
|
||||
unsigned HiOpc;
|
||||
unsigned LoOpc = getNonAtomic6432Opcode(Opc, HiOpc);
|
||||
unsigned cL = MRI.createVirtualRegister(RC8);
|
||||
unsigned cH = MRI.createVirtualRegister(RC8);
|
||||
unsigned cL32 = MRI.createVirtualRegister(RC);
|
||||
unsigned cH32 = MRI.createVirtualRegister(RC);
|
||||
unsigned cc = MRI.createVirtualRegister(RC);
|
||||
// cl := cmp src_lo, lo
|
||||
BuildMI(mainMBB, DL, TII->get(X86::CMP32rr))
|
||||
.addReg(SrcLoReg).addReg(LoReg);
|
||||
BuildMI(mainMBB, DL, TII->get(LoOpc), cL);
|
||||
BuildMI(mainMBB, DL, TII->get(X86::MOVZX32rr8), cL32).addReg(cL);
|
||||
// ch := cmp src_hi, hi
|
||||
BuildMI(mainMBB, DL, TII->get(X86::CMP32rr))
|
||||
.addReg(SrcHiReg).addReg(HiReg);
|
||||
BuildMI(mainMBB, DL, TII->get(HiOpc), cH);
|
||||
BuildMI(mainMBB, DL, TII->get(X86::MOVZX32rr8), cH32).addReg(cH);
|
||||
// cc := if (src_hi == hi) ? cl : ch;
|
||||
if (Subtarget->hasCMov()) {
|
||||
BuildMI(mainMBB, DL, TII->get(X86::CMOVE32rr), cc)
|
||||
.addReg(cH32).addReg(cL32);
|
||||
} else {
|
||||
MIB = BuildMI(mainMBB, DL, TII->get(X86::CMOV_GR32), cc)
|
||||
.addReg(cH32).addReg(cL32)
|
||||
.addImm(X86::COND_E);
|
||||
mainMBB = EmitLoweredSelect(MIB, mainMBB);
|
||||
}
|
||||
BuildMI(mainMBB, DL, TII->get(X86::TEST32rr)).addReg(cc).addReg(cc);
|
||||
if (Subtarget->hasCMov()) {
|
||||
BuildMI(mainMBB, DL, TII->get(X86::CMOVNE32rr), t1L)
|
||||
.addReg(SrcLoReg).addReg(LoReg);
|
||||
BuildMI(mainMBB, DL, TII->get(X86::CMOVNE32rr), t1H)
|
||||
.addReg(SrcHiReg).addReg(HiReg);
|
||||
} else {
|
||||
MIB = BuildMI(mainMBB, DL, TII->get(X86::CMOV_GR32), t1L)
|
||||
.addReg(SrcLoReg).addReg(LoReg)
|
||||
.addImm(X86::COND_NE);
|
||||
mainMBB = EmitLoweredSelect(MIB, mainMBB);
|
||||
MIB = BuildMI(mainMBB, DL, TII->get(X86::CMOV_GR32), t1H)
|
||||
.addReg(SrcHiReg).addReg(HiReg)
|
||||
.addImm(X86::COND_NE);
|
||||
mainMBB = EmitLoweredSelect(MIB, mainMBB);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case X86::ATOMSWAP6432: {
|
||||
unsigned HiOpc;
|
||||
unsigned LoOpc = getNonAtomic6432Opcode(Opc, HiOpc);
|
||||
@ -13381,6 +13455,10 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
|
||||
case X86::ATOMNAND6432:
|
||||
case X86::ATOMADD6432:
|
||||
case X86::ATOMSUB6432:
|
||||
case X86::ATOMMAX6432:
|
||||
case X86::ATOMMIN6432:
|
||||
case X86::ATOMUMAX6432:
|
||||
case X86::ATOMUMIN6432:
|
||||
case X86::ATOMSWAP6432:
|
||||
return EmitAtomicLoadArith6432(MI, BB);
|
||||
|
||||
|
@ -348,6 +348,10 @@ namespace llvm {
|
||||
ATOMXOR64_DAG,
|
||||
ATOMAND64_DAG,
|
||||
ATOMNAND64_DAG,
|
||||
ATOMMAX64_DAG,
|
||||
ATOMMIN64_DAG,
|
||||
ATOMUMAX64_DAG,
|
||||
ATOMUMIN64_DAG,
|
||||
ATOMSWAP64_DAG,
|
||||
|
||||
// LCMPXCHG_DAG, LCMPXCHG8_DAG, LCMPXCHG16_DAG - Compare and swap.
|
||||
|
51
test/CodeGen/X86/atomic-minmax-i6432.ll
Normal file
51
test/CodeGen/X86/atomic-minmax-i6432.ll
Normal file
@ -0,0 +1,51 @@
|
||||
; RUN: llc -march=x86 -mattr=+cmov -mtriple=i386-pc-linux < %s | FileCheck %s
|
||||
@sc64 = external global i64
|
||||
|
||||
define void @atomic_maxmin_i6432() {
|
||||
; CHECK: atomic_maxmin_i6432
|
||||
%1 = atomicrmw max i64* @sc64, i64 5 acquire
|
||||
; CHECK: [[LABEL:.LBB[0-9]+_[0-9]+]]
|
||||
; CHECK: cmpl
|
||||
; CHECK: setl
|
||||
; CHECK: cmpl
|
||||
; CHECK: setl
|
||||
; CHECK: cmovne
|
||||
; CHECK: cmovne
|
||||
; CHECK: lock
|
||||
; CHECK-NEXT: cmpxchg8b
|
||||
; CHECK: jne [[LABEL]]
|
||||
%2 = atomicrmw min i64* @sc64, i64 6 acquire
|
||||
; CHECK: [[LABEL:.LBB[0-9]+_[0-9]+]]
|
||||
; CHECK: cmpl
|
||||
; CHECK: setg
|
||||
; CHECK: cmpl
|
||||
; CHECK: setg
|
||||
; CHECK: cmovne
|
||||
; CHECK: cmovne
|
||||
; CHECK: lock
|
||||
; CHECK-NEXT: cmpxchg8b
|
||||
; CHECK: jne [[LABEL]]
|
||||
%3 = atomicrmw umax i64* @sc64, i64 7 acquire
|
||||
; CHECK: [[LABEL:.LBB[0-9]+_[0-9]+]]
|
||||
; CHECK: cmpl
|
||||
; CHECK: setb
|
||||
; CHECK: cmpl
|
||||
; CHECK: setb
|
||||
; CHECK: cmovne
|
||||
; CHECK: cmovne
|
||||
; CHECK: lock
|
||||
; CHECK-NEXT: cmpxchg8b
|
||||
; CHECK: jne [[LABEL]]
|
||||
%4 = atomicrmw umin i64* @sc64, i64 8 acquire
|
||||
; CHECK: [[LABEL:.LBB[0-9]+_[0-9]+]]
|
||||
; CHECK: cmpl
|
||||
; CHECK: seta
|
||||
; CHECK: cmpl
|
||||
; CHECK: seta
|
||||
; CHECK: cmovne
|
||||
; CHECK: cmovne
|
||||
; CHECK: lock
|
||||
; CHECK-NEXT: cmpxchg8b
|
||||
; CHECK: jne [[LABEL]]
|
||||
ret void
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
; RUN: llc < %s -O0 -march=x86 -mcpu=corei7 | FileCheck %s --check-prefix X32
|
||||
; XFAIL: *
|
||||
|
||||
@sc64 = external global i64
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user