[X86] Don't transform atomic-load-add into an inc/dec when inc/dec is slow

llvm-svn: 219357
This commit is contained in:
Robin Morisset 2014-10-08 23:16:23 +00:00
parent 33702a31e8
commit 6f3d04e4b6
2 changed files with 21 additions and 3 deletions

View File

@ -1706,7 +1706,8 @@ static const uint16_t AtomicOpcTbl[AtomicOpcEnd][AtomicSzEnd] = {
static SDValue getAtomicLoadArithTargetConstant(SelectionDAG *CurDAG,
SDLoc dl,
enum AtomicOpc &Op, MVT NVT,
SDValue Val) {
SDValue Val,
const X86Subtarget *Subtarget) {
if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Val)) {
int64_t CNVal = CN->getSExtValue();
// Quit if not 32-bit imm.
@ -1721,7 +1722,7 @@ static SDValue getAtomicLoadArithTargetConstant(SelectionDAG *CurDAG,
// For atomic-load-add, we could do some optimizations.
if (Op == ADD) {
// Translate to INC/DEC if ADD by 1 or -1.
if ((CNVal == 1) || (CNVal == -1)) {
if (((CNVal == 1) || (CNVal == -1)) && !Subtarget->slowIncDec()) {
Op = (CNVal == 1) ? INC : DEC;
// No more constant operand after being translated into INC/DEC.
return SDValue();
@ -1793,7 +1794,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadArith(SDNode *Node, MVT NVT) {
break;
}
Val = getAtomicLoadArithTargetConstant(CurDAG, dl, Op, NVT, Val);
Val = getAtomicLoadArithTargetConstant(CurDAG, dl, Op, NVT, Val, Subtarget);
bool isUnOp = !Val.getNode();
bool isCN = Val.getNode() && (Val.getOpcode() == ISD::TargetConstant);

View File

@ -1,4 +1,5 @@
; RUN: llc < %s -march=x86-64 -verify-machineinstrs | FileCheck %s
; RUN: llc < %s -march=x86-64 -mattr=slow-incdec -verify-machineinstrs | FileCheck %s --check-prefix SLOW_INC
; rdar://7103704
@ -14,6 +15,8 @@ define void @inc4(i64* nocapture %p) nounwind ssp {
entry:
; CHECK-LABEL: inc4:
; CHECK: incq
; SLOW_INC-LABEL: inc4:
; SLOW_INC-NOT: incq
%0 = atomicrmw add i64* %p, i64 1 monotonic
ret void
}
@ -39,6 +42,8 @@ define void @inc3(i8* nocapture %p) nounwind ssp {
entry:
; CHECK-LABEL: inc3:
; CHECK: incb
; SLOW_INC-LABEL: inc3:
; SLOW_INC-NOT: incb
%0 = atomicrmw add i8* %p, i8 1 monotonic
ret void
}
@ -64,6 +69,8 @@ define void @inc2(i16* nocapture %p) nounwind ssp {
entry:
; CHECK-LABEL: inc2:
; CHECK: incw
; SLOW_INC-LABEL: inc2:
; SLOW_INC-NOT: incw
%0 = atomicrmw add i16* %p, i16 1 monotonic
ret void
}
@ -89,6 +96,8 @@ define void @inc1(i32* nocapture %p) nounwind ssp {
entry:
; CHECK-LABEL: inc1:
; CHECK: incl
; SLOW_INC-LABEL: inc1:
; SLOW_INC-NOT: incl
%0 = atomicrmw add i32* %p, i32 1 monotonic
ret void
}
@ -113,6 +122,8 @@ define void @dec4(i64* nocapture %p) nounwind ssp {
entry:
; CHECK-LABEL: dec4:
; CHECK: decq
; SLOW_INC-LABEL: dec4:
; SLOW_INC-NOT: decq
%0 = atomicrmw sub i64* %p, i64 1 monotonic
ret void
}
@ -138,6 +149,8 @@ define void @dec3(i8* nocapture %p) nounwind ssp {
entry:
; CHECK-LABEL: dec3:
; CHECK: decb
; SLOW_INC-LABEL: dec3:
; SLOW_INC-NOT: decb
%0 = atomicrmw sub i8* %p, i8 1 monotonic
ret void
}
@ -163,6 +176,8 @@ define void @dec2(i16* nocapture %p) nounwind ssp {
entry:
; CHECK-LABEL: dec2:
; CHECK: decw
; SLOW_INC-LABEL: dec2:
; SLOW_INC-NOT: decw
%0 = atomicrmw sub i16* %p, i16 1 monotonic
ret void
}
@ -189,6 +204,8 @@ define void @dec1(i32* nocapture %p) nounwind ssp {
entry:
; CHECK-LABEL: dec1:
; CHECK: decl
; SLOW_INC-LABEL: dec1:
; SLOW_INC-NOT: decl
%0 = atomicrmw sub i32* %p, i32 1 monotonic
ret void
}