diff --git a/lib/Target/X86/X86ISelDAGToDAG.cpp b/lib/Target/X86/X86ISelDAGToDAG.cpp index 15c19177056..cc8db35262f 100644 --- a/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -23,6 +23,7 @@ #include "llvm/Intrinsics.h" #include "llvm/Support/CFG.h" #include "llvm/Type.h" +#include "llvm/CodeGen/FunctionLoweringInfo.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -1351,7 +1352,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) { bool isInc = false, isDec = false, isSub = false, isCN = false; ConstantSDNode *CN = dyn_cast(Val); - if (CN) { + if (CN && CN->getSExtValue() == (int32_t)CN->getSExtValue()) { isCN = true; int64_t CNVal = CN->getSExtValue(); if (CNVal == 1) @@ -1371,6 +1372,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) { Val = Val.getOperand(1); } + DebugLoc dl = Node->getDebugLoc(); unsigned Opc = 0; switch (NVT.getSimpleVT().SimpleTy) { default: return 0; @@ -1462,7 +1464,6 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadAdd(SDNode *Node, EVT NVT) { break; } - DebugLoc dl = Node->getDebugLoc(); SDValue Undef = SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, NVT), 0); MachineSDNode::mmo_iterator MemOp = MF->allocateMemRefsArray(1); @@ -1579,7 +1580,7 @@ SDNode *X86DAGToDAGISel::SelectAtomicLoadArith(SDNode *Node, EVT NVT) { bool isCN = false; ConstantSDNode *CN = dyn_cast(Val); - if (CN) { + if (CN && (int32_t)CN->getSExtValue() == CN->getSExtValue()) { isCN = true; Val = CurDAG->getTargetConstant(CN->getSExtValue(), NVT); } diff --git a/test/CodeGen/X86/atomic-or.ll b/test/CodeGen/X86/atomic-or.ll index cd622908aca..9db6f6f06dd 100644 --- a/test/CodeGen/X86/atomic-or.ll +++ b/test/CodeGen/X86/atomic-or.ll @@ -2,17 +2,35 @@ ; rdar://9692967 -define void @do_the_sync(i64* %p, i32 %b) nounwind { +define void @t1(i64* %p, i32 %b) nounwind { entry: %p.addr = alloca i64*, align 8 store i64* %p, i64** %p.addr, align 8 %tmp = load i64** %p.addr, align 8 call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) +; CHECK: t1: +; CHECK: movl $2147483648, %eax ; CHECK: lock -; CHECK-NEXT: orq $2147483648 +; CHECK-NEXT: orq %rax, (%rdi) %0 = call i64 @llvm.atomic.load.or.i64.p0i64(i64* %tmp, i64 2147483648) call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) ret void } + +define void @t2(i64* %p, i32 %b) nounwind { +entry: + %p.addr = alloca i64*, align 8 + store i64* %p, i64** %p.addr, align 8 + %tmp = load i64** %p.addr, align 8 + call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) +; CHECK: t2: +; CHECK-NOT: movl +; CHECK: lock +; CHECK-NEXT: orq $2147483644, (%rdi) + %0 = call i64 @llvm.atomic.load.or.i64.p0i64(i64* %tmp, i64 2147483644) + call void @llvm.memory.barrier(i1 true, i1 true, i1 true, i1 true, i1 true) + ret void +} + declare i64 @llvm.atomic.load.or.i64.p0i64(i64* nocapture, i64) nounwind declare void @llvm.memory.barrier(i1, i1, i1, i1, i1) nounwind