Index: lib/Target/X86/X86InstructionSelector.cpp =================================================================== --- lib/Target/X86/X86InstructionSelector.cpp +++ lib/Target/X86/X86InstructionSelector.cpp @@ -512,10 +512,22 @@ LLT Ty = MRI.getType(DefReg); const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); + assert(I.hasOneMemOperand()); auto &MemOp = **I.memoperands_begin(); - if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { - LLVM_DEBUG(dbgs() << "Atomic load/store not supported yet\n"); - return false; + if (MemOp.isAtomic()) { + // Note: for unordered operations, we rely on the fact the appropriate MMO + // is already on the instruction we're mutating, and thus we don't need to + // make any changes. So long as we select an opcode which is capable of + // loading or storing the appropriate size atomically, the rest of the + // backend is required to respect the MMO state. + if (!MemOp.isUnordered()) { + LLVM_DEBUG(dbgs() << "Atomic ordering not supported yet\n"); + return false; + } + if (MemOp.getAlignment() < Ty.getSizeInBits()/8) { + LLVM_DEBUG(dbgs() << "Unaligned atomics not supported yet\n"); + return false; + } } unsigned NewOpc = getLoadStoreOp(Ty, RB, Opc, MemOp.getAlignment()); Index: test/CodeGen/X86/atomic-unordered.ll =================================================================== --- test/CodeGen/X86/atomic-unordered.ll +++ test/CodeGen/X86/atomic-unordered.ll @@ -1,6 +1,8 @@ ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py ; RUN: llc -O0 < %s -mtriple=x86_64-linux-generic -verify-machineinstrs -mattr=sse2 | FileCheck --check-prefix=CHECK-O0 %s +; RUN: llc -O0 -global-isel < %s -mtriple=x86_64-linux-generic -verify-machineinstrs -mattr=sse2 | FileCheck --check-prefix=CHECK-O0-GISEL %s ; RUN: llc -O3 < %s -mtriple=x86_64-linux-generic -verify-machineinstrs -mattr=sse2 | FileCheck --check-prefix=CHECK-O3 %s +; RUN: llc -O3 -global-isel < %s -mtriple=x86_64-linux-generic -verify-machineinstrs -mattr=sse2 | FileCheck --check-prefix=CHECK-O3-GISEL %s define i8 @load_i8(i8* %ptr) { ; CHECK-O0-LABEL: load_i8: @@ -8,10 +10,20 @@ ; CHECK-O0-NEXT: movb (%rdi), %al ; CHECK-O0-NEXT: retq ; +; CHECK-O0-GISEL-LABEL: load_i8: +; CHECK-O0-GISEL: # %bb.1: +; CHECK-O0-GISEL-NEXT: movb (%rdi), %al +; CHECK-O0-GISEL-NEXT: retq +; ; CHECK-O3-LABEL: load_i8: ; CHECK-O3: # %bb.0: ; CHECK-O3-NEXT: movb (%rdi), %al ; CHECK-O3-NEXT: retq +; +; CHECK-O3-GISEL-LABEL: load_i8: +; CHECK-O3-GISEL: # %bb.0: +; CHECK-O3-GISEL-NEXT: movb (%rdi), %al +; CHECK-O3-GISEL-NEXT: retq %v = load atomic i8, i8* %ptr unordered, align 1 ret i8 %v } @@ -23,10 +35,21 @@ ; CHECK-O0-NEXT: movb %al, (%rdi) ; CHECK-O0-NEXT: retq ; +; CHECK-O0-GISEL-LABEL: store_i8: +; CHECK-O0-GISEL: # %bb.1: +; CHECK-O0-GISEL-NEXT: movb %sil, %al +; CHECK-O0-GISEL-NEXT: movb %al, (%rdi) +; CHECK-O0-GISEL-NEXT: retq +; ; CHECK-O3-LABEL: store_i8: ; CHECK-O3: # %bb.0: ; CHECK-O3-NEXT: movb %sil, (%rdi) ; CHECK-O3-NEXT: retq +; +; CHECK-O3-GISEL-LABEL: store_i8: +; CHECK-O3-GISEL: # %bb.0: +; CHECK-O3-GISEL-NEXT: movb %sil, (%rdi) +; CHECK-O3-GISEL-NEXT: retq store atomic i8 %v, i8* %ptr unordered, align 1 ret void } @@ -37,10 +60,20 @@ ; CHECK-O0-NEXT: movw (%rdi), %ax ; CHECK-O0-NEXT: retq ; +; CHECK-O0-GISEL-LABEL: load_i16: +; CHECK-O0-GISEL: # %bb.1: +; CHECK-O0-GISEL-NEXT: movw (%rdi), %ax +; CHECK-O0-GISEL-NEXT: retq +; ; CHECK-O3-LABEL: load_i16: ; CHECK-O3: # %bb.0: ; CHECK-O3-NEXT: movzwl (%rdi), %eax ; CHECK-O3-NEXT: retq +; +; CHECK-O3-GISEL-LABEL: load_i16: +; CHECK-O3-GISEL: # %bb.0: +; CHECK-O3-GISEL-NEXT: movzwl (%rdi), %eax +; CHECK-O3-GISEL-NEXT: retq %v = load atomic i16, i16* %ptr unordered, align 2 ret i16 %v } @@ -53,10 +86,21 @@ ; CHECK-O0-NEXT: movw %ax, (%rdi) ; CHECK-O0-NEXT: retq ; +; CHECK-O0-GISEL-LABEL: store_i16: +; CHECK-O0-GISEL: # %bb.1: +; CHECK-O0-GISEL-NEXT: movw %si, %ax +; CHECK-O0-GISEL-NEXT: movw %ax, (%rdi) +; CHECK-O0-GISEL-NEXT: retq +; ; CHECK-O3-LABEL: store_i16: ; CHECK-O3: # %bb.0: ; CHECK-O3-NEXT: movw %si, (%rdi) ; CHECK-O3-NEXT: retq +; +; CHECK-O3-GISEL-LABEL: store_i16: +; CHECK-O3-GISEL: # %bb.0: +; CHECK-O3-GISEL-NEXT: movw %si, (%rdi) +; CHECK-O3-GISEL-NEXT: retq store atomic i16 %v, i16* %ptr unordered, align 2 ret void } @@ -67,10 +111,20 @@ ; CHECK-O0-NEXT: movl (%rdi), %eax ; CHECK-O0-NEXT: retq ; +; CHECK-O0-GISEL-LABEL: load_i32: +; CHECK-O0-GISEL: # %bb.1: +; CHECK-O0-GISEL-NEXT: movl (%rdi), %eax +; CHECK-O0-GISEL-NEXT: retq +; ; CHECK-O3-LABEL: load_i32: ; CHECK-O3: # %bb.0: ; CHECK-O3-NEXT: movl (%rdi), %eax ; CHECK-O3-NEXT: retq +; +; CHECK-O3-GISEL-LABEL: load_i32: +; CHECK-O3-GISEL: # %bb.0: +; CHECK-O3-GISEL-NEXT: movl (%rdi), %eax +; CHECK-O3-GISEL-NEXT: retq %v = load atomic i32, i32* %ptr unordered, align 4 ret i32 %v } @@ -81,10 +135,20 @@ ; CHECK-O0-NEXT: movl %esi, (%rdi) ; CHECK-O0-NEXT: retq ; +; CHECK-O0-GISEL-LABEL: store_i32: +; CHECK-O0-GISEL: # %bb.1: +; CHECK-O0-GISEL-NEXT: movl %esi, (%rdi) +; CHECK-O0-GISEL-NEXT: retq +; ; CHECK-O3-LABEL: store_i32: ; CHECK-O3: # %bb.0: ; CHECK-O3-NEXT: movl %esi, (%rdi) ; CHECK-O3-NEXT: retq +; +; CHECK-O3-GISEL-LABEL: store_i32: +; CHECK-O3-GISEL: # %bb.0: +; CHECK-O3-GISEL-NEXT: movl %esi, (%rdi) +; CHECK-O3-GISEL-NEXT: retq store atomic i32 %v, i32* %ptr unordered, align 4 ret void } @@ -95,10 +159,20 @@ ; CHECK-O0-NEXT: movq (%rdi), %rax ; CHECK-O0-NEXT: retq ; +; CHECK-O0-GISEL-LABEL: load_i64: +; CHECK-O0-GISEL: # %bb.1: +; CHECK-O0-GISEL-NEXT: movq (%rdi), %rax +; CHECK-O0-GISEL-NEXT: retq +; ; CHECK-O3-LABEL: load_i64: ; CHECK-O3: # %bb.0: ; CHECK-O3-NEXT: movq (%rdi), %rax ; CHECK-O3-NEXT: retq +; +; CHECK-O3-GISEL-LABEL: load_i64: +; CHECK-O3-GISEL: # %bb.0: +; CHECK-O3-GISEL-NEXT: movq (%rdi), %rax +; CHECK-O3-GISEL-NEXT: retq %v = load atomic i64, i64* %ptr unordered, align 8 ret i64 %v } @@ -109,10 +183,20 @@ ; CHECK-O0-NEXT: movq %rsi, (%rdi) ; CHECK-O0-NEXT: retq ; +; CHECK-O0-GISEL-LABEL: store_i64: +; CHECK-O0-GISEL: # %bb.1: +; CHECK-O0-GISEL-NEXT: movq %rsi, (%rdi) +; CHECK-O0-GISEL-NEXT: retq +; ; CHECK-O3-LABEL: store_i64: ; CHECK-O3: # %bb.0: ; CHECK-O3-NEXT: movq %rsi, (%rdi) ; CHECK-O3-NEXT: retq +; +; CHECK-O3-GISEL-LABEL: store_i64: +; CHECK-O3-GISEL: # %bb.0: +; CHECK-O3-GISEL-NEXT: movq %rsi, (%rdi) +; CHECK-O3-GISEL-NEXT: retq store atomic i64 %v, i64* %ptr unordered, align 8 ret void }