forked from OSchip/llvm-project
				
			X86: correct 64-bit atomics on 32-bit
We would emit a libcall for a 64-bit atomic on x86 after SVN r212119. This was due to the misuse of hasCmpxchg16 to indicate if cmpxchg8b was supported on a 32-bit target. They were added at different times and would result in the border condition being mishandled. This fixes the border case to emit the cmpxchg8b instruction for 64-bit atomic operations on x86 at the cost of restoring a long-standing bug in the codegen. We emit a cmpxchg8b on all x86 targets even where the CPU does not support this instruction (pre-Pentium CPUs). Although this bug should be fixed, this was present prior to SVN r212119 and this change, so this is not really introducing a regression. llvm-svn: 212956
This commit is contained in:
		
							parent
							
								
									271ac58eb3
								
							
						
					
					
						commit
						b51d464f1e
					
				| 
						 | 
				
			
			@ -98,25 +98,21 @@ bool X86AtomicExpandPass::runOnFunction(Function &F) {
 | 
			
		|||
  return MadeChange;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Returns true if operations on the given type will need to use either
 | 
			
		||||
/// cmpxchg8b or cmpxchg16b. This occurs if the type is 1 step up from the
 | 
			
		||||
/// native width, and the instructions are available (otherwise we leave them
 | 
			
		||||
/// alone to become __sync_fetch_and_... calls).
 | 
			
		||||
/// Returns true if the operand type is 1 step up from the native width, and
 | 
			
		||||
/// the corresponding cmpxchg8b or cmpxchg16b instruction is available
 | 
			
		||||
/// (otherwise we leave them alone to become __sync_fetch_and_... calls).
 | 
			
		||||
bool X86AtomicExpandPass::needsCmpXchgNb(llvm::Type *MemType) {
 | 
			
		||||
  const X86Subtarget &Subtarget = TM->getSubtarget<X86Subtarget>();
 | 
			
		||||
  if (!Subtarget.hasCmpxchg16b())
 | 
			
		||||
    return false;
 | 
			
		||||
 | 
			
		||||
  unsigned CmpXchgNbWidth = Subtarget.is64Bit() ? 128 : 64;
 | 
			
		||||
 | 
			
		||||
  unsigned OpWidth = MemType->getPrimitiveSizeInBits();
 | 
			
		||||
  if (OpWidth == CmpXchgNbWidth)
 | 
			
		||||
    return true;
 | 
			
		||||
 | 
			
		||||
  if (OpWidth == 64)
 | 
			
		||||
    return !Subtarget.is64Bit();  // FIXME this should be Subtarget.hasCmpxchg8b
 | 
			
		||||
  if (OpWidth == 128)
 | 
			
		||||
    return Subtarget.hasCmpxchg16b();
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool X86AtomicExpandPass::shouldExpandAtomicRMW(AtomicRMWInst *AI) {
 | 
			
		||||
  const X86Subtarget &Subtarget = TM->getSubtarget<X86Subtarget>();
 | 
			
		||||
  unsigned NativeWidth = Subtarget.is64Bit() ? 64 : 32;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,5 @@
 | 
			
		|||
; RUN: llc -mtriple=i386-linux-gnu %s -o - | FileCheck %s
 | 
			
		||||
; XFAIL: *
 | 
			
		||||
 | 
			
		||||
define i64 @test_add(i64* %addr, i64 %inc) {
 | 
			
		||||
; CHECK-LABEL: test_add:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue