diff --git a/test/CodeGen/X86/pr37025.ll b/test/CodeGen/X86/pr37025.ll new file mode 100644 index 00000000000..be8ab8d3846 --- /dev/null +++ b/test/CodeGen/X86/pr37025.ll @@ -0,0 +1,125 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=x86_64-- | FileCheck %s + +; PR37025 +; +;#include +;#include +; +;void func2(); +; +;void func(_Atomic(unsigned long) * obj, void * obj2) +;{ +; if (atomic_fetch_sub(obj, 1) == 1 && obj2) +; func2(); +;} + +define void @test_dec_select(i64* nocapture %0, i8* readnone %1) { +; CHECK-LABEL: test_dec_select: +; CHECK: # %bb.0: +; CHECK-NEXT: lock decq (%rdi) +; CHECK-NEXT: jne .LBB0_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: testq %rsi, %rsi +; CHECK-NEXT: je .LBB0_2 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: jmp func2 # TAILCALL +; CHECK-NEXT: .LBB0_2: +; CHECK-NEXT: retq + %3 = atomicrmw sub i64* %0, i64 1 seq_cst + %4 = icmp eq i64 %3, 1 + %5 = icmp ne i8* %1, null + %6 = select i1 %4, i1 %5, i1 false + br i1 %6, label %7, label %8 + +7: ; preds = %2 + tail call void @func2() + br label %8 + +8: ; preds = %7, %2 + ret void +} + +define void @test_dec_select_commute(i64* nocapture %0, i8* readnone %1) { +; CHECK-LABEL: test_dec_select_commute: +; CHECK: # %bb.0: +; CHECK-NEXT: movq $-1, %rax +; CHECK-NEXT: lock xaddq %rax, (%rdi) +; CHECK-NEXT: testq %rsi, %rsi +; CHECK-NEXT: je .LBB1_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: cmpq $1, %rax +; CHECK-NEXT: jne .LBB1_2 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: jmp func2 # TAILCALL +; CHECK-NEXT: .LBB1_2: +; CHECK-NEXT: retq + %3 = atomicrmw sub i64* %0, i64 1 seq_cst + %4 = icmp eq i64 %3, 1 + %5 = icmp ne i8* %1, null + %6 = select i1 %5, i1 %4, i1 false + br i1 %6, label %7, label %8 + +7: ; preds = %2 + tail call void @func2() + br label %8 + +8: ; preds = %7, %2 + ret void +} + +define void @test_dec_and(i64* nocapture %0, i8* readnone %1) { +; CHECK-LABEL: test_dec_and: +; CHECK: # %bb.0: +; CHECK-NEXT: movq $-1, %rax +; CHECK-NEXT: lock xaddq %rax, (%rdi) +; CHECK-NEXT: testq %rsi, %rsi +; CHECK-NEXT: je .LBB2_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: cmpq $1, %rax +; CHECK-NEXT: jne .LBB2_2 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: jmp func2 # TAILCALL +; CHECK-NEXT: .LBB2_2: +; CHECK-NEXT: retq + %3 = atomicrmw sub i64* %0, i64 1 seq_cst + %4 = icmp eq i64 %3, 1 + %5 = icmp ne i8* %1, null + %6 = and i1 %5, %4 + br i1 %6, label %7, label %8 + +7: ; preds = %2 + tail call void @func2() + br label %8 + +8: ; preds = %7, %2 + ret void +} + +define void @test_dec_and_commute(i64* nocapture %0, i8* readnone %1) { +; CHECK-LABEL: test_dec_and_commute: +; CHECK: # %bb.0: +; CHECK-NEXT: lock decq (%rdi) +; CHECK-NEXT: jne .LBB3_2 +; CHECK-NEXT: # %bb.1: +; CHECK-NEXT: testq %rsi, %rsi +; CHECK-NEXT: je .LBB3_2 +; CHECK-NEXT: # %bb.3: +; CHECK-NEXT: jmp func2 # TAILCALL +; CHECK-NEXT: .LBB3_2: +; CHECK-NEXT: retq + %3 = atomicrmw sub i64* %0, i64 1 seq_cst + %4 = icmp eq i64 %3, 1 + %5 = icmp ne i8* %1, null + %6 = and i1 %4, %5 + br i1 %6, label %7, label %8 + +7: ; preds = %2 + tail call void @func2() + br label %8 + +8: ; preds = %7, %2 + ret void +} + +declare dso_local void @func2()