[SelectionDAG] Drop unnecessary lower bound check in `lowerRangeToAssertZExt` (#196785)
Drop the `Lo.isMinValue()` check in `lowerRangeToAssertZExt`.
The check was introduced in 2bba779272a2 when the bit width was computed
via `logBase2(Hi)`, which required `Lo == 0` for correctness. It is no
longer needed since 9e04befb0979 when we switched to
`getUnsignedMax().getActiveBits()` for bit width.
The change in `DAGCombiner.cpp` is to prevent a regression in
`llvm/test/CodeGen/AMDGPU/llvm.amdgcn.wavefrontsize.ll`. I wasn't able
to construct an individual test for it.
---------
Co-authored-by: nikic <github@npopov.com>diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 3d65c82..14bf2b7 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16213,6 +16213,10 @@
AssertVT == cast<VTSDNode>(N0.getOperand(1))->getVT())
return N0;
+ // fold (assert?ext c, vt) -> c
+ if (isa<ConstantSDNode>(N0))
+ return N0;
+
if (N0.getOpcode() == ISD::TRUNCATE && N0.hasOneUse() &&
N0.getOperand(0).getOpcode() == Opcode) {
// We have an assert, truncate, assert sandwich. Make one stronger assert
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 68ae86d..5753d74 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -10852,10 +10852,6 @@
if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped())
return Op;
- APInt Lo = CR->getUnsignedMin();
- if (!Lo.isMinValue())
- return Op;
-
APInt Hi = CR->getUnsignedMax();
unsigned Bits = std::max(Hi.getActiveBits(),
static_cast<unsigned>(IntegerType::MIN_INT_BITS));
diff --git a/llvm/test/CodeGen/X86/call-range-attr.ll b/llvm/test/CodeGen/X86/call-range-attr.ll
new file mode 100644
index 0000000..80e03e9
--- /dev/null
+++ b/llvm/test/CodeGen/X86/call-range-attr.ll
@@ -0,0 +1,73 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
+; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
+
+declare i64 @returns_i64()
+
+define i64 @call_range_nonzero_lo() nounwind {
+; CHECK-LABEL: call_range_nonzero_lo:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: callq returns_i64@PLT
+; CHECK-NEXT: andq $-8, %rax
+; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: retq
+ %v = call range(i64 1, 2305843009213693952) i64 @returns_i64()
+ %r = and i64 %v, 2305843009213693944
+ ret i64 %r
+}
+
+define i64 @call_range_zero_lo() nounwind {
+; CHECK-LABEL: call_range_zero_lo:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: callq returns_i64@PLT
+; CHECK-NEXT: andl $-8, %eax
+; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: retq
+ %v = call range(i64 0, 256) i64 @returns_i64()
+ %r = and i64 %v, 248
+ ret i64 %r
+}
+
+define i64 @call_range_narrow() nounwind {
+; CHECK-LABEL: call_range_narrow:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: callq returns_i64@PLT
+; CHECK-NEXT: andl $-8, %eax
+; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: retq
+ %v = call range(i64 100, 256) i64 @returns_i64()
+ %r = and i64 %v, 248
+ ret i64 %r
+}
+
+; Negative tests
+
+define i64 @call_no_range() nounwind {
+; CHECK-LABEL: call_no_range:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: callq returns_i64@PLT
+; CHECK-NEXT: movabsq $2305843009213693944, %rcx # imm = 0x1FFFFFFFFFFFFFF8
+; CHECK-NEXT: andq %rcx, %rax
+; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: retq
+ %v = call i64 @returns_i64()
+ %r = and i64 %v, 2305843009213693944
+ ret i64 %r
+}
+
+define i64 @call_wrapped_range() nounwind {
+; CHECK-LABEL: call_wrapped_range:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: callq returns_i64@PLT
+; CHECK-NEXT: movabsq $2305843009213693944, %rcx # imm = 0x1FFFFFFFFFFFFFF8
+; CHECK-NEXT: andq %rcx, %rax
+; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: retq
+ %v = call range(i64 -100, 100) i64 @returns_i64()
+ %r = and i64 %v, 2305843009213693944
+ ret i64 %r
+}