[llvm] 44cac91 - Fix `FindSingleBitChange` to handle NOT(V) where V is not an Instruction
Noah Goldstein via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 23 03:46:53 PST 2023
Author: Noah Goldstein
Date: 2023-01-23T03:35:56-08:00
New Revision: 44cac911e51a15fcfac7a9888ad0146191a14730
URL: https://github.com/llvm/llvm-project/commit/44cac911e51a15fcfac7a9888ad0146191a14730
DIFF: https://github.com/llvm/llvm-project/commit/44cac911e51a15fcfac7a9888ad0146191a14730.diff
LOG: Fix `FindSingleBitChange` to handle NOT(V) where V is not an Instruction
Was previously buggy to assume that NOT'd Value was always an
instruction. If the NOT'd value is not an Instruction, we should just
return as its either a constant, in which can we will re-run the logic
after constant-folding, or its a type we can't evaluate anyways.
This is a follow up to: `D140939`
Reviewed By: pengfei, RKSimon
Differential Revision: https://reviews.llvm.org/D142339
Added:
Modified:
llvm/lib/Target/X86/X86ISelLowering.cpp
llvm/test/CodeGen/X86/atomic-rm-bit-test-64.ll
llvm/test/CodeGen/X86/atomic-rm-bit-test.ll
Removed:
################################################################################
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 3339ac943c1e..70c7a0825b2c 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -31505,7 +31505,11 @@ static std::pair<Value *, BitTestKind> FindSingleBitChange(Value *V) {
match(I, m_Sub(m_AllOnes(), m_Value(PeekI)))) {
Not = true;
I = dyn_cast<Instruction>(PeekI);
- assert(I != nullptr);
+
+ // If I is constant, it will fold and we can evaluate later. If its an
+ // argument or something of that nature, we can't analyze.
+ if (I == nullptr)
+ return {nullptr, UndefBit};
}
// We can only use 1 << X without more sophisticated analysis. C << X where
// C is a power of 2 but not 1 can result in zero which cannot be translated
diff --git a/llvm/test/CodeGen/X86/atomic-rm-bit-test-64.ll b/llvm/test/CodeGen/X86/atomic-rm-bit-test-64.ll
index 3dcf8c6c00ef..ad85a090010f 100644
--- a/llvm/test/CodeGen/X86/atomic-rm-bit-test-64.ll
+++ b/llvm/test/CodeGen/X86/atomic-rm-bit-test-64.ll
@@ -1586,3 +1586,23 @@ 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
+}
diff --git a/llvm/test/CodeGen/X86/atomic-rm-bit-test.ll b/llvm/test/CodeGen/X86/atomic-rm-bit-test.ll
index 5a5d207b3373..5594d13a234d 100644
--- a/llvm/test/CodeGen/X86/atomic-rm-bit-test.ll
+++ b/llvm/test/CodeGen/X86/atomic-rm-bit-test.ll
@@ -6873,3 +6873,140 @@ entry:
%and1 = and i32 %and, %shl
ret i32 %and1
}
+
+define i32 @atomic_xor_with_not_arg(ptr %v, i32 %c) nounwind {
+; X86-LABEL: atomic_xor_with_not_arg:
+; X86: # %bb.0: # %entry
+; X86-NEXT: pushl %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: notl %edx
+; X86-NEXT: movl (%ecx), %eax
+; X86-NEXT: .p2align 4, 0x90
+; X86-NEXT: .LBB123_1: # %atomicrmw.start
+; X86-NEXT: # =>This Inner Loop Header: Depth=1
+; X86-NEXT: movl %eax, %esi
+; X86-NEXT: xorl %edx, %esi
+; X86-NEXT: lock cmpxchgl %esi, (%ecx)
+; X86-NEXT: jne .LBB123_1
+; X86-NEXT: # %bb.2: # %atomicrmw.end
+; X86-NEXT: popl %esi
+; X86-NEXT: retl
+;
+; X64-LABEL: atomic_xor_with_not_arg:
+; X64: # %bb.0: # %entry
+; X64-NEXT: notl %esi
+; X64-NEXT: movl (%rdi), %eax
+; X64-NEXT: .p2align 4, 0x90
+; X64-NEXT: .LBB123_1: # %atomicrmw.start
+; X64-NEXT: # =>This Inner Loop Header: Depth=1
+; X64-NEXT: movl %eax, %ecx
+; X64-NEXT: xorl %esi, %ecx
+; X64-NEXT: lock cmpxchgl %ecx, (%rdi)
+; X64-NEXT: jne .LBB123_1
+; X64-NEXT: # %bb.2: # %atomicrmw.end
+; X64-NEXT: retq
+entry:
+ %0 = xor i32 %c, -1
+ %1 = atomicrmw xor ptr %v, i32 %0 monotonic, align 4
+ ret i32 %1
+}
+
+define i16 @atomic_or_with_not_arg(ptr %v, i16 %c) nounwind {
+; X86-LABEL: atomic_or_with_not_arg:
+; X86: # %bb.0: # %entry
+; X86-NEXT: pushl %esi
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: notl %edx
+; X86-NEXT: movzwl (%ecx), %eax
+; X86-NEXT: .p2align 4, 0x90
+; X86-NEXT: .LBB124_1: # %atomicrmw.start
+; X86-NEXT: # =>This Inner Loop Header: Depth=1
+; X86-NEXT: movl %eax, %esi
+; X86-NEXT: orl %edx, %esi
+; X86-NEXT: # kill: def $ax killed $ax killed $eax
+; X86-NEXT: lock cmpxchgw %si, (%ecx)
+; X86-NEXT: # kill: def $ax killed $ax def $eax
+; X86-NEXT: jne .LBB124_1
+; X86-NEXT: # %bb.2: # %atomicrmw.end
+; X86-NEXT: # kill: def $ax killed $ax killed $eax
+; X86-NEXT: popl %esi
+; X86-NEXT: retl
+;
+; X64-LABEL: atomic_or_with_not_arg:
+; X64: # %bb.0: # %entry
+; X64-NEXT: notl %esi
+; X64-NEXT: movzwl (%rdi), %eax
+; X64-NEXT: .p2align 4, 0x90
+; X64-NEXT: .LBB124_1: # %atomicrmw.start
+; X64-NEXT: # =>This Inner Loop Header: Depth=1
+; X64-NEXT: movl %eax, %ecx
+; X64-NEXT: orl %esi, %ecx
+; X64-NEXT: # kill: def $ax killed $ax killed $eax
+; X64-NEXT: lock cmpxchgw %cx, (%rdi)
+; X64-NEXT: # kill: def $ax killed $ax def $eax
+; X64-NEXT: jne .LBB124_1
+; X64-NEXT: # %bb.2: # %atomicrmw.end
+; X64-NEXT: # kill: def $ax killed $ax killed $eax
+; X64-NEXT: retq
+entry:
+ %0 = xor i16 %c, -1
+ %1 = atomicrmw or ptr %v, i16 %0 monotonic, align 2
+ ret i16 %1
+}
+
+define i8 @atomic_and_with_not_arg(ptr %v, i8 %c) nounwind {
+; X86-LABEL: atomic_and_with_not_arg:
+; X86: # %bb.0: # %entry
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movzbl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: notb %dl
+; X86-NEXT: movzbl (%ecx), %eax
+; X86-NEXT: .p2align 4, 0x90
+; X86-NEXT: .LBB125_1: # %atomicrmw.start
+; X86-NEXT: # =>This Inner Loop Header: Depth=1
+; X86-NEXT: movb %al, %ah
+; X86-NEXT: orb %dl, %ah
+; X86-NEXT: lock cmpxchgb %ah, (%ecx)
+; X86-NEXT: jne .LBB125_1
+; X86-NEXT: # %bb.2: # %atomicrmw.end
+; X86-NEXT: retl
+;
+; X64-LABEL: atomic_and_with_not_arg:
+; X64: # %bb.0: # %entry
+; X64-NEXT: notb %sil
+; X64-NEXT: movzbl (%rdi), %eax
+; X64-NEXT: .p2align 4, 0x90
+; X64-NEXT: .LBB125_1: # %atomicrmw.start
+; X64-NEXT: # =>This Inner Loop Header: Depth=1
+; X64-NEXT: movl %eax, %ecx
+; X64-NEXT: orb %sil, %cl
+; X64-NEXT: lock cmpxchgb %cl, (%rdi)
+; X64-NEXT: jne .LBB125_1
+; X64-NEXT: # %bb.2: # %atomicrmw.end
+; X64-NEXT: retq
+entry:
+ %0 = xor i8 %c, -1
+ %1 = atomicrmw or ptr %v, i8 %0 monotonic, align 1
+ ret i8 %1
+}
+
+define weak_odr void @atomic_and_with_not_const() nounwind {
+; X86-LABEL: atomic_and_with_not_const:
+; X86: # %bb.0: # %entry
+; X86-NEXT: retl
+;
+; X64-LABEL: atomic_and_with_not_const:
+; X64: # %bb.0: # %entry
+; X64-NEXT: retq
+ entry:
+ br label %if.end19
+cont11: ; No predecessors!
+ %not = xor i32 0, -1
+ %0 = atomicrmw and ptr null, i32 %not monotonic, align 4
+ %and13 = and i32 %0, 0
+ br label %if.end19
+if.end19: ; preds = %cont11, %entry
+ ret void
+}
More information about the llvm-commits
mailing list