[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