[llvm] ae71609 - [SDAG] Lower range attribute to AssertZext (#95450)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 14 01:04:39 PDT 2024
Author: Andreas Jonson
Date: 2024-06-14T10:04:33+02:00
New Revision: ae71609e91ec9f38df7e92ba3c50a1f9cebb772e
URL: https://github.com/llvm/llvm-project/commit/ae71609e91ec9f38df7e92ba3c50a1f9cebb772e
DIFF: https://github.com/llvm/llvm-project/commit/ae71609e91ec9f38df7e92ba3c50a1f9cebb772e.diff
LOG: [SDAG] Lower range attribute to AssertZext (#95450)
Add support for range attributes on calls, in addition to range metadata.
Added:
Modified:
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 2b82d87429391..98555b39db03c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4487,6 +4487,17 @@ static const MDNode *getRangeMetadata(const Instruction &I) {
return I.getMetadata(LLVMContext::MD_range);
}
+static std::optional<ConstantRange> getRange(const Instruction &I) {
+ if (const auto *CB = dyn_cast<CallBase>(&I)) {
+ // see comment in getRangeMetadata about this check
+ if (CB->hasRetAttr(Attribute::NoUndef))
+ return CB->getRange();
+ }
+ if (const MDNode *Range = getRangeMetadata(I))
+ return getConstantRangeFromMetadata(*Range);
+ return std::nullopt;
+}
+
void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
if (I.isAtomic())
return visitAtomicLoad(I);
@@ -10230,19 +10241,16 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) {
SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
const Instruction &I,
SDValue Op) {
- const MDNode *Range = getRangeMetadata(I);
- if (!Range)
- return Op;
+ std::optional<ConstantRange> CR = getRange(I);
- ConstantRange CR = getConstantRangeFromMetadata(*Range);
- if (CR.isFullSet() || CR.isEmptySet() || CR.isUpperWrapped())
+ if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped())
return Op;
- APInt Lo = CR.getUnsignedMin();
+ APInt Lo = CR->getUnsignedMin();
if (!Lo.isMinValue())
return Op;
- APInt Hi = CR.getUnsignedMax();
+ APInt Hi = CR->getUnsignedMax();
unsigned Bits = std::max(Hi.getActiveBits(),
static_cast<unsigned>(IntegerType::MIN_INT_BITS));
diff --git a/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll b/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
index 5b9a734c49825..5af8189b4e0d7 100644
--- a/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
+++ b/llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll
@@ -34,6 +34,28 @@ entry:
ret i32 %and
}
+; and can be eliminated
+; CHECK-LABEL: {{^}}test_call_known_max_range_attr:
+; CHECK: bl foo
+; CHECK-NOT: and
+; CHECK: ret
+define i32 @test_call_known_max_range_attr() #0 {
+entry:
+ %id = tail call noundef range(i32 0, 1024) i32 @foo()
+ %and = and i32 %id, 1023
+ ret i32 %and
+}
+
+; CHECK-LABEL: {{^}}test_call_known_max_range_attr_no_noundef:
+; CHECK: bl foo
+; CHECK: and w{{[0-9]+}}, w0, #0x3ff
+; CHECK: ret
+define i32 @test_call_known_max_range_attr_no_noundef() #0 {
+entry:
+ %id = tail call range(i32 0, 1024) i32 @foo()
+ %and = and i32 %id, 1023
+ ret i32 %and
+}
declare i32 @foo()
diff --git a/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll b/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
index 1c595b7fb5e1e..2cf37c68b8b40 100644
--- a/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
+++ b/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
@@ -34,6 +34,24 @@ define i64 @widen_assertzext(ptr %x) nounwind {
ret i64 %d
}
+define i64 @widen_assertzext_range_attr(ptr %x) nounwind {
+; CHECK-LABEL: widen_assertzext_range_attr:
+; CHECK: # %bb.0:
+; CHECK-NEXT: pushq %rax
+; CHECK-NEXT: callq test2 at PLT
+; CHECK-NEXT: movb $127, %al
+; CHECK-NEXT: kmovw %eax, %k1
+; CHECK-NEXT: vpexpandq %zmm0, %zmm0 {%k1} {z}
+; CHECK-NEXT: vextracti32x4 $3, %zmm0, %xmm0
+; CHECK-NEXT: vmovq %xmm0, %rax
+; CHECK-NEXT: popq %rcx
+; CHECK-NEXT: vzeroupper
+; CHECK-NEXT: retq
+ %e = call noundef range(i64 0, 2) <7 x i64> @test2()
+ %d = extractelement <7 x i64> %e, i32 6
+ ret i64 %d
+}
+
declare <16 x i64> @test()
declare <7 x i64> @test2()
!0 = !{ i64 0, i64 2 }
More information about the llvm-commits
mailing list