[llvm] [SDAG] Lower range attribute to AssertZext (PR #95450)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 13 14:23:36 PDT 2024
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/95450
>From d0df14673894d773bfe9a93e07bdde163fdd2ac6 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Thu, 13 Jun 2024 20:15:22 +0200
Subject: [PATCH 1/3] [SDAG] Test lower range attribute to AssertZext
---
.../AArch64/lower-range-metadata-func-call.ll | 22 +++++++++++++++++++
.../CodeGen/X86/legalize-vec-assertzext.ll | 15 +++++++++++++
2 files changed, 37 insertions(+)
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..eb61b62fe738f 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
}
+; CHECK-LABEL: {{^}}test_call_known_max_range_attr:
+; CHECK: bl foo
+; CHECK: and w{{[0-9]+}}, w0, #0x3ff
+; 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..5fa1649b15c70 100644
--- a/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
+++ b/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
@@ -34,6 +34,21 @@ 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: 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 }
>From 65238d636e934f116a822c81429242435d321de2 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Thu, 13 Jun 2024 22:44:07 +0200
Subject: [PATCH 2/3] [SDAG] Lower range attribute to AssertZext
---
.../SelectionDAG/SelectionDAGBuilder.cpp | 23 +++++++++++++------
.../AArch64/lower-range-metadata-func-call.ll | 4 ++--
.../CodeGen/X86/legalize-vec-assertzext.ll | 3 +++
3 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index be5e0f6ef058b..5d21a905c316c 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4487,6 +4487,18 @@ 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);
@@ -10229,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 eb61b62fe738f..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,9 +34,10 @@ entry:
ret i32 %and
}
+; and can be eliminated
; CHECK-LABEL: {{^}}test_call_known_max_range_attr:
; CHECK: bl foo
-; CHECK: and w{{[0-9]+}}, w0, #0x3ff
+; CHECK-NOT: and
; CHECK: ret
define i32 @test_call_known_max_range_attr() #0 {
entry:
@@ -56,7 +57,6 @@ entry:
ret i32 %and
}
-
declare i32 @foo()
attributes #0 = { norecurse nounwind }
diff --git a/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll b/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
index 5fa1649b15c70..2cf37c68b8b40 100644
--- a/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
+++ b/llvm/test/CodeGen/X86/legalize-vec-assertzext.ll
@@ -39,6 +39,9 @@ define i64 @widen_assertzext_range_attr(ptr %x) nounwind {
; 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
>From 7fb26d6a8bfac1271472bef866f4a2e347a84a5a Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Thu, 13 Jun 2024 23:23:21 +0200
Subject: [PATCH 3/3] fixup! [SDAG] Lower range attribute to AssertZext
---
llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 5d21a905c316c..04581ac11b7ed 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -4493,9 +4493,8 @@ static std::optional<ConstantRange> getRange(const Instruction &I) {
if (CB->hasRetAttr(Attribute::NoUndef))
return CB->getRange();
}
- if (const MDNode *Range = getRangeMetadata(I)) {
+ if (const MDNode *Range = getRangeMetadata(I))
return getConstantRangeFromMetadata(*Range);
- }
return std::nullopt;
}
More information about the llvm-commits
mailing list