diff options
author | Andreas Jonson <andjo403@hotmail.com> | 2024-06-14 10:04:33 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-06-14 10:04:33 +0200 |
commit | ae71609e91ec9f38df7e92ba3c50a1f9cebb772e (patch) | |
tree | 6a2ad37d583bfd3cf255781d61b0a6d374e5934a | |
parent | 706e1975400b3f30bd406b694bb711a7c7dbe1c4 (diff) | |
download | llvm-ae71609e91ec9f38df7e92ba3c50a1f9cebb772e.zip llvm-ae71609e91ec9f38df7e92ba3c50a1f9cebb772e.tar.gz llvm-ae71609e91ec9f38df7e92ba3c50a1f9cebb772e.tar.bz2 |
[SDAG] Lower range attribute to AssertZext (#95450)
Add support for range attributes on calls, in addition to range metadata.
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 22 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll | 22 | ||||
-rw-r--r-- | llvm/test/CodeGen/X86/legalize-vec-assertzext.ll | 18 |
3 files changed, 55 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 2b82d87..98555b3 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 5b9a734..5af8189 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 1c595b7..2cf37c6 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@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 } |