blob: ad85a090010f8eaa5596c6aca142b693c03a7fd1 [file] [log] [blame]
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
define i64 @atomic_shl1_xor_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_xor_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btcq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%and = and i64 %shl, %0
ret i64 %and
}
define i64 @atomic_shl2_xor_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl2_xor_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $2, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB1_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: xorq %rdx, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB1_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: andq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl i64 2, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%and = and i64 %0, %shl
ret i64 %and
}
define i64 @atomic_shl1_neq_xor_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_neq_xor_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB2_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB2_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: incb %cl
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: andq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%add = add i64 %c, 1
%shl1 = shl nuw i64 1, %add
%and = and i64 %0, %shl1
ret i64 %and
}
define i64 @atomic_shl1_small_mask_xor_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_small_mask_xor_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $31, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btcq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 31
%shl = shl nuw nsw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%and = and i64 %0, %shl
ret i64 %and
}
define i64 @atomic_shl1_mask0_xor_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask0_xor_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btcq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%shl1 = shl nuw i64 1, %c
%and = and i64 %shl1, %0
ret i64 %and
}
define i64 @atomic_shl1_mask1_xor_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask1_xor_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btcq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%rem = and i64 %c, 63
%shl1 = shl nuw i64 1, %rem
%and = and i64 %0, %shl1
ret i64 %and
}
define i64 @atomic_shl1_mask01_xor_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask01_xor_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btcq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%and = and i64 %0, %shl
ret i64 %and
}
define i64 @atomic_blsi_xor_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_blsi_xor_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: negq %rcx
; CHECK-NEXT: andq %rsi, %rcx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB7_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rdx
; CHECK-NEXT: xorq %rcx, %rdx
; CHECK-NEXT: lock cmpxchgq %rdx, (%rdi)
; CHECK-NEXT: jne .LBB7_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: andq %rcx, %rax
; CHECK-NEXT: retq
entry:
%sub = sub i64 0, %c
%and = and i64 %sub, %c
%0 = atomicrmw xor ptr %v, i64 %and monotonic, align 8
%and3 = and i64 %0, %and
ret i64 %and3
}
define i64 @atomic_shl1_xor_64_gpr_valz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_xor_64_gpr_valz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB8_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB8_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setae %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%1 = sub i64 -1, %0
%2 = lshr i64 %1, %c
%conv = and i64 %2, 1
ret i64 %conv
}
define i64 @atomic_shl2_xor_64_gpr_valz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl2_xor_64_gpr_valz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $2, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB9_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: xorq %rdx, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB9_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: testq %rax, %rdx
; CHECK-NEXT: sete %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl i64 2, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%and = and i64 %shl, %0
%tobool.not = icmp eq i64 %and, 0
%conv = zext i1 %tobool.not to i64
ret i64 %conv
}
define i64 @atomic_shl1_neq_xor_64_gpr_valz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_neq_xor_64_gpr_valz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB10_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB10_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: incb %cl
; CHECK-NEXT: movzbl %cl, %edx
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: btq %rdx, %rax
; CHECK-NEXT: setae %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%add = add i64 %c, 1
%1 = xor i64 %0, -1
%2 = lshr i64 %1, %add
%conv = and i64 %2, 1
ret i64 %conv
}
define i64 @atomic_shl1_small_mask_xor_64_gpr_valz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_small_mask_xor_64_gpr_valz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $31, %ecx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB11_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB11_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btl %ecx, %eax
; CHECK-NEXT: setae %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 31
%shl = shl nuw nsw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%1 = xor i64 %0, -1
%2 = lshr i64 %1, %rem
%conv = and i64 %2, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask0_xor_64_gpr_valz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask0_xor_64_gpr_valz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB12_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB12_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setae %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%1 = xor i64 %0, -1
%2 = lshr i64 %1, %c
%conv = and i64 %2, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask1_xor_64_gpr_valz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask1_xor_64_gpr_valz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB13_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB13_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setae %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%rem = and i64 %c, 63
%1 = xor i64 %0, -1
%2 = lshr i64 %1, %rem
%conv = and i64 %2, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask01_xor_64_gpr_valz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask01_xor_64_gpr_valz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB14_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB14_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setae %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%1 = xor i64 %0, -1
%2 = lshr i64 %1, %rem
%conv = and i64 %2, 1
ret i64 %conv
}
define i64 @atomic_blsi_xor_64_gpr_valz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_blsi_xor_64_gpr_valz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rdx
; CHECK-NEXT: negq %rdx
; CHECK-NEXT: andq %rsi, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB15_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: xorq %rdx, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB15_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: testq %rdx, %rax
; CHECK-NEXT: sete %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%sub = sub i64 0, %c
%and = and i64 %sub, %c
%0 = atomicrmw xor ptr %v, i64 %and monotonic, align 8
%and3 = and i64 %0, %and
%tobool.not = icmp eq i64 %and3, 0
%conv = zext i1 %tobool.not to i64
ret i64 %conv
}
define i64 @atomic_shl1_xor_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_xor_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB16_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB16_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%1 = lshr i64 %0, %c
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl2_xor_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl2_xor_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $2, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB17_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: xorq %rdx, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB17_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: testq %rdx, %rax
; CHECK-NEXT: setne %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl i64 2, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%and = and i64 %0, %shl
%tobool = icmp ne i64 %and, 0
%conv = zext i1 %tobool to i64
ret i64 %conv
}
define i64 @atomic_shl1_neq_xor_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_neq_xor_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB18_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB18_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: incb %cl
; CHECK-NEXT: movzbl %cl, %edx
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: btq %rdx, %rax
; CHECK-NEXT: setb %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%add = add i64 %c, 1
%1 = lshr i64 %0, %add
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl1_small_mask_xor_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_small_mask_xor_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $31, %ecx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB19_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB19_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btl %ecx, %eax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 31
%shl = shl nuw nsw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%1 = lshr i64 %0, %rem
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask0_xor_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask0_xor_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB20_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB20_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%1 = lshr i64 %0, %c
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask1_xor_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask1_xor_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB21_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB21_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%rem = and i64 %c, 63
%1 = lshr i64 %0, %rem
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask01_xor_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask01_xor_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB22_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: xorq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB22_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%0 = atomicrmw xor ptr %v, i64 %shl monotonic, align 8
%1 = lshr i64 %0, %rem
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_blsi_xor_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_blsi_xor_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rdx
; CHECK-NEXT: negq %rdx
; CHECK-NEXT: andq %rsi, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB23_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: xorq %rdx, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB23_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: testq %rdx, %rax
; CHECK-NEXT: setne %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%sub = sub i64 0, %c
%and = and i64 %sub, %c
%0 = atomicrmw xor ptr %v, i64 %and monotonic, align 8
%and3 = and i64 %0, %and
%tobool = icmp ne i64 %and3, 0
%conv = zext i1 %tobool to i64
ret i64 %conv
}
define i64 @atomic_shl1_and_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_and_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btrq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = sub i64 -1, %shl
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %0, %shl
ret i64 %and
}
define i64 @atomic_shl2_and_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl2_and_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $2, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq %rdx, %rcx
; CHECK-NEXT: notq %rcx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB25_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rcx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB25_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: andq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl i64 2, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %0, %shl
ret i64 %and
}
define i64 @atomic_shl1_neq_and_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_neq_and_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq $-2, %rdx
; CHECK-NEXT: rolq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB26_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB26_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: incb %cl
; CHECK-NEXT: movl $1, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: andq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%add = add i64 %c, 1
%shl1 = shl nuw i64 1, %add
%and = and i64 %0, %shl1
ret i64 %and
}
define i64 @atomic_shl1_small_mask_and_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_small_mask_and_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $31, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btrq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 31
%shl = shl nuw nsw i64 1, %rem
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %0, %shl
ret i64 %and
}
define i64 @atomic_shl1_mask0_and_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask0_and_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btrq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%not = sub i64 -1, %shl
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%shl1 = shl nuw i64 1, %c
%and = and i64 %0, %shl1
ret i64 %and
}
define i64 @atomic_shl1_mask1_and_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask1_and_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btrq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%rem = and i64 %c, 63
%shl1 = shl nuw i64 1, %rem
%and = and i64 %0, %shl1
ret i64 %and
}
define i64 @atomic_shl1_mask01_and_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask01_and_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $63, %ecx
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btrq %rcx, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %0, %shl
ret i64 %and
}
define i64 @atomic_blsi_and_64_gpr_val(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_blsi_and_64_gpr_val:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: negq %rcx
; CHECK-NEXT: andq %rsi, %rcx
; CHECK-NEXT: movq %rcx, %rdx
; CHECK-NEXT: notq %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB31_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB31_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: andq %rax, %rcx
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%sub = sub i64 0, %c
%and = and i64 %sub, %c
%not = xor i64 %and, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and3 = and i64 %and, %0
ret i64 %and3
}
define i64 @atomic_shl1_and_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_and_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq $-2, %rdx
; CHECK-NEXT: rolq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB32_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB32_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%1 = lshr i64 %0, %c
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl2_and_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl2_and_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $2, %edx
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq %rdx, %rcx
; CHECK-NEXT: notq %rcx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB33_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rcx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB33_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: testq %rax, %rdx
; CHECK-NEXT: setne %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl i64 2, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %shl, %0
%tobool = icmp ne i64 %and, 0
%conv = zext i1 %tobool to i64
ret i64 %conv
}
define i64 @atomic_shl1_neq_and_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_neq_and_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq $-2, %rdx
; CHECK-NEXT: rolq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB34_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB34_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: incb %cl
; CHECK-NEXT: movzbl %cl, %edx
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: btq %rdx, %rax
; CHECK-NEXT: setb %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%add = add i64 %c, 1
%1 = lshr i64 %0, %add
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl1_small_mask_and_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_small_mask_and_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: andl $31, %ecx
; CHECK-NEXT: movq $-2, %rdx
; CHECK-NEXT: rolq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB35_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB35_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btl %ecx, %eax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 31
%shl = shl nuw nsw i64 1, %rem
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%1 = lshr i64 %0, %rem
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask0_and_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask0_and_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq $-2, %rdx
; CHECK-NEXT: rolq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB36_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB36_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%1 = lshr i64 %0, %c
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask1_and_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask1_and_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq $-2, %rdx
; CHECK-NEXT: rolq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB37_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB37_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %edx, %edx
; CHECK-NEXT: btq %rcx, %rax
; CHECK-NEXT: setb %dl
; CHECK-NEXT: movq %rdx, %rax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%rem = and i64 %c, 63
%1 = lshr i64 %0, %rem
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_shl1_mask01_and_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask01_and_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl %ecx, %edx
; CHECK-NEXT: andl $63, %edx
; CHECK-NEXT: movq $-2, %rsi
; CHECK-NEXT: # kill: def $cl killed $cl killed $rcx
; CHECK-NEXT: rolq %cl, %rsi
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB38_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: andq %rsi, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB38_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: btq %rdx, %rax
; CHECK-NEXT: setb %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%1 = lshr i64 %0, %rem
%conv = and i64 %1, 1
ret i64 %conv
}
define i64 @atomic_blsi_and_64_gpr_valnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_blsi_and_64_gpr_valnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rdx
; CHECK-NEXT: negq %rdx
; CHECK-NEXT: andq %rsi, %rdx
; CHECK-NEXT: movq %rdx, %rcx
; CHECK-NEXT: notq %rcx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB39_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rcx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB39_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: xorl %ecx, %ecx
; CHECK-NEXT: testq %rdx, %rax
; CHECK-NEXT: setne %cl
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%sub = sub i64 0, %c
%and = and i64 %sub, %c
%not = xor i64 %and, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and3 = and i64 %0, %and
%tobool = icmp ne i64 %and3, 0
%conv = zext i1 %tobool to i64
ret i64 %conv
}
define i64 @atomic_shl1_and_64_gpr_brnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_and_64_gpr_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: andl $63, %eax
; CHECK-NEXT: lock btrq %rax, (%rdi)
; CHECK-NEXT: jae .LBB40_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: movq (%rdi,%rsi,8), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB40_1:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %shl, %0
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 %c
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl2_and_64_gpr_brnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl2_and_64_gpr_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movl $2, %edx
; CHECK-NEXT: shlq %cl, %rdx
; CHECK-NEXT: movq %rdx, %rsi
; CHECK-NEXT: notq %rsi
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB41_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %r8
; CHECK-NEXT: andq %rsi, %r8
; CHECK-NEXT: lock cmpxchgq %r8, (%rdi)
; CHECK-NEXT: jne .LBB41_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: testq %rdx, %rax
; CHECK-NEXT: je .LBB41_3
; CHECK-NEXT: # %bb.4: # %if.then
; CHECK-NEXT: movq (%rdi,%rcx,8), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB41_3:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%shl = shl i64 2, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %0, %shl
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 %c
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_neq_and_64_gpr_brnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_neq_and_64_gpr_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: movq $-2, %rdx
; CHECK-NEXT: rolq %cl, %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB42_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rsi
; CHECK-NEXT: andq %rdx, %rsi
; CHECK-NEXT: lock cmpxchgq %rsi, (%rdi)
; CHECK-NEXT: jne .LBB42_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: leal 1(%rcx), %edx
; CHECK-NEXT: movzbl %dl, %edx
; CHECK-NEXT: btq %rdx, %rax
; CHECK-NEXT: jae .LBB42_3
; CHECK-NEXT: # %bb.4: # %if.then
; CHECK-NEXT: movq (%rdi,%rcx,8), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB42_3:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%add = add i64 %c, 1
%shl1 = shl nuw i64 1, %add
%and = and i64 %0, %shl1
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 %c
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_small_mask_and_64_gpr_brnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_small_mask_and_64_gpr_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: andl $31, %esi
; CHECK-NEXT: lock btrq %rsi, (%rdi)
; CHECK-NEXT: jae .LBB43_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: movq (%rdi,%rsi,8), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB43_1:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 31
%shl = shl nuw nsw i64 1, %rem
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %0, %shl
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 %rem
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_mask0_and_64_gpr_brnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask0_and_64_gpr_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: andl $63, %eax
; CHECK-NEXT: lock btrq %rax, (%rdi)
; CHECK-NEXT: jae .LBB44_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: movq (%rdi,%rsi,8), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB44_1:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%shl1 = shl nuw i64 1, %c
%and = and i64 %shl1, %0
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 %c
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_mask1_and_64_gpr_brnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask1_and_64_gpr_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: andl $63, %eax
; CHECK-NEXT: lock btrq %rax, (%rdi)
; CHECK-NEXT: jae .LBB45_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: movq (%rdi,%rsi,8), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB45_1:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%shl = shl nuw i64 1, %c
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%rem = and i64 %c, 63
%shl1 = shl nuw i64 1, %rem
%and = and i64 %0, %shl1
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 %c
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_mask01_and_64_gpr_brnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_shl1_mask01_and_64_gpr_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movl %esi, %eax
; CHECK-NEXT: andl $63, %eax
; CHECK-NEXT: lock btrq %rax, (%rdi)
; CHECK-NEXT: jae .LBB46_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: movq (%rdi,%rsi,8), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB46_1:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%rem = and i64 %c, 63
%shl = shl nuw i64 1, %rem
%not = xor i64 %shl, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and = and i64 %0, %shl
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 %c
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_blsi_and_64_gpr_brnz(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_blsi_and_64_gpr_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq %rsi, %rcx
; CHECK-NEXT: negq %rcx
; CHECK-NEXT: andq %rsi, %rcx
; CHECK-NEXT: movq %rcx, %rdx
; CHECK-NEXT: notq %rdx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB47_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %r8
; CHECK-NEXT: andq %rdx, %r8
; CHECK-NEXT: lock cmpxchgq %r8, (%rdi)
; CHECK-NEXT: jne .LBB47_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: testq %rcx, %rax
; CHECK-NEXT: je .LBB47_3
; CHECK-NEXT: # %bb.4: # %if.then
; CHECK-NEXT: movq (%rdi,%rsi,8), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB47_3:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%sub = sub i64 0, %c
%and = and i64 %sub, %c
%not = xor i64 %and, -1
%0 = atomicrmw and ptr %v, i64 %not monotonic, align 8
%and3 = and i64 %0, %and
%tobool.not = icmp eq i64 %and3, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 %c
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_xor_64_const_br(ptr %v) nounwind {
; CHECK-LABEL: atomic_shl1_xor_64_const_br:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btcq $4, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: shlq $4, %rax
; CHECK-NEXT: je .LBB48_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: movq 32(%rdi), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB48_1:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%0 = atomicrmw xor ptr %v, i64 16 monotonic, align 8
%and = and i64 %0, 16
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 4
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_neq_xor_64_const_br(ptr %v) nounwind {
; CHECK-LABEL: atomic_shl1_neq_xor_64_const_br:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB49_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: xorq $16, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB49_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: movl $123, %ecx
; CHECK-NEXT: testb $32, %al
; CHECK-NEXT: je .LBB49_4
; CHECK-NEXT: # %bb.3: # %if.then
; CHECK-NEXT: movq 32(%rdi), %rcx
; CHECK-NEXT: .LBB49_4: # %return
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%0 = atomicrmw xor ptr %v, i64 16 monotonic, align 8
%and = and i64 %0, 32
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 4
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_xor_64_const_brz(ptr %v) nounwind {
; CHECK-LABEL: atomic_shl1_xor_64_const_brz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btcq $4, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: shlq $4, %rax
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: je .LBB50_1
; CHECK-NEXT: # %bb.2: # %return
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB50_1: # %if.then
; CHECK-NEXT: movq 32(%rdi), %rax
; CHECK-NEXT: retq
entry:
%0 = atomicrmw xor ptr %v, i64 16 monotonic, align 8
%and = and i64 16, %0
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %if.then, label %return
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 4
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_neq_xor_64_const_brz(ptr %v) nounwind {
; CHECK-LABEL: atomic_shl1_neq_xor_64_const_brz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB51_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: xorq $16, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB51_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: movl $123, %ecx
; CHECK-NEXT: testb $32, %al
; CHECK-NEXT: jne .LBB51_4
; CHECK-NEXT: # %bb.3: # %if.then
; CHECK-NEXT: movq 32(%rdi), %rcx
; CHECK-NEXT: .LBB51_4: # %return
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%0 = atomicrmw xor ptr %v, i64 16 monotonic, align 8
%and = and i64 %0, 32
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %if.then, label %return
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 4
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_xor_64_const_brnz(ptr %v) nounwind {
; CHECK-LABEL: atomic_shl1_xor_64_const_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: xorl %eax, %eax
; CHECK-NEXT: lock btcq $4, (%rdi)
; CHECK-NEXT: setb %al
; CHECK-NEXT: shlq $4, %rax
; CHECK-NEXT: je .LBB52_1
; CHECK-NEXT: # %bb.2: # %if.then
; CHECK-NEXT: movq 32(%rdi), %rax
; CHECK-NEXT: retq
; CHECK-NEXT: .LBB52_1:
; CHECK-NEXT: movl $123, %eax
; CHECK-NEXT: retq
entry:
%0 = atomicrmw xor ptr %v, i64 16 monotonic, align 8
%and = and i64 %0, 16
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 4
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_shl1_neq_xor_64_const_brnz(ptr %v) nounwind {
; CHECK-LABEL: atomic_shl1_neq_xor_64_const_brnz:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB53_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rcx
; CHECK-NEXT: xorq $16, %rcx
; CHECK-NEXT: lock cmpxchgq %rcx, (%rdi)
; CHECK-NEXT: jne .LBB53_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: movl $123, %ecx
; CHECK-NEXT: testb $32, %al
; CHECK-NEXT: je .LBB53_4
; CHECK-NEXT: # %bb.3: # %if.then
; CHECK-NEXT: movq 32(%rdi), %rcx
; CHECK-NEXT: .LBB53_4: # %return
; CHECK-NEXT: movq %rcx, %rax
; CHECK-NEXT: retq
entry:
%0 = atomicrmw xor ptr %v, i64 16 monotonic, align 8
%and = and i64 %0, 32
%tobool.not = icmp eq i64 %and, 0
br i1 %tobool.not, label %return, label %if.then
if.then: ; preds = %entry
%arrayidx = getelementptr inbounds i64, ptr %v, i64 4
%1 = load i64, ptr %arrayidx, align 8
br label %return
return: ; preds = %entry, %if.then
%retval.0 = phi i64 [ %1, %if.then ], [ 123, %entry ]
ret i64 %retval.0
}
define i64 @atomic_and_with_not_arg(ptr %v, i64 %c) nounwind {
; CHECK-LABEL: atomic_and_with_not_arg:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: movq $-1, %rcx
; CHECK-NEXT: movq (%rdi), %rax
; CHECK-NEXT: .p2align 4, 0x90
; CHECK-NEXT: .LBB54_1: # %atomicrmw.start
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: movq %rax, %rdx
; CHECK-NEXT: orq %rcx, %rdx
; CHECK-NEXT: lock cmpxchgq %rdx, (%rdi)
; CHECK-NEXT: jne .LBB54_1
; CHECK-NEXT: # %bb.2: # %atomicrmw.end
; CHECK-NEXT: retq
entry:
%0 = xor i64 0, -1
%1 = atomicrmw or ptr %v, i64 %0 monotonic, align 8
ret i64 %1
}