Skip to content

Commit ae71609

Browse files
authored
[SDAG] Lower range attribute to AssertZext (#95450)
Add support for range attributes on calls, in addition to range metadata.
1 parent 706e197 commit ae71609

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4487,6 +4487,17 @@ static const MDNode *getRangeMetadata(const Instruction &I) {
44874487
return I.getMetadata(LLVMContext::MD_range);
44884488
}
44894489

4490+
static std::optional<ConstantRange> getRange(const Instruction &I) {
4491+
if (const auto *CB = dyn_cast<CallBase>(&I)) {
4492+
// see comment in getRangeMetadata about this check
4493+
if (CB->hasRetAttr(Attribute::NoUndef))
4494+
return CB->getRange();
4495+
}
4496+
if (const MDNode *Range = getRangeMetadata(I))
4497+
return getConstantRangeFromMetadata(*Range);
4498+
return std::nullopt;
4499+
}
4500+
44904501
void SelectionDAGBuilder::visitLoad(const LoadInst &I) {
44914502
if (I.isAtomic())
44924503
return visitAtomicLoad(I);
@@ -10230,19 +10241,16 @@ void SelectionDAGBuilder::visitVACopy(const CallInst &I) {
1023010241
SDValue SelectionDAGBuilder::lowerRangeToAssertZExt(SelectionDAG &DAG,
1023110242
const Instruction &I,
1023210243
SDValue Op) {
10233-
const MDNode *Range = getRangeMetadata(I);
10234-
if (!Range)
10235-
return Op;
10244+
std::optional<ConstantRange> CR = getRange(I);
1023610245

10237-
ConstantRange CR = getConstantRangeFromMetadata(*Range);
10238-
if (CR.isFullSet() || CR.isEmptySet() || CR.isUpperWrapped())
10246+
if (!CR || CR->isFullSet() || CR->isEmptySet() || CR->isUpperWrapped())
1023910247
return Op;
1024010248

10241-
APInt Lo = CR.getUnsignedMin();
10249+
APInt Lo = CR->getUnsignedMin();
1024210250
if (!Lo.isMinValue())
1024310251
return Op;
1024410252

10245-
APInt Hi = CR.getUnsignedMax();
10253+
APInt Hi = CR->getUnsignedMax();
1024610254
unsigned Bits = std::max(Hi.getActiveBits(),
1024710255
static_cast<unsigned>(IntegerType::MIN_INT_BITS));
1024810256

llvm/test/CodeGen/AArch64/lower-range-metadata-func-call.ll

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,28 @@ entry:
3434
ret i32 %and
3535
}
3636

37+
; and can be eliminated
38+
; CHECK-LABEL: {{^}}test_call_known_max_range_attr:
39+
; CHECK: bl foo
40+
; CHECK-NOT: and
41+
; CHECK: ret
42+
define i32 @test_call_known_max_range_attr() #0 {
43+
entry:
44+
%id = tail call noundef range(i32 0, 1024) i32 @foo()
45+
%and = and i32 %id, 1023
46+
ret i32 %and
47+
}
48+
49+
; CHECK-LABEL: {{^}}test_call_known_max_range_attr_no_noundef:
50+
; CHECK: bl foo
51+
; CHECK: and w{{[0-9]+}}, w0, #0x3ff
52+
; CHECK: ret
53+
define i32 @test_call_known_max_range_attr_no_noundef() #0 {
54+
entry:
55+
%id = tail call range(i32 0, 1024) i32 @foo()
56+
%and = and i32 %id, 1023
57+
ret i32 %and
58+
}
3759

3860
declare i32 @foo()
3961

llvm/test/CodeGen/X86/legalize-vec-assertzext.ll

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,24 @@ define i64 @widen_assertzext(ptr %x) nounwind {
3434
ret i64 %d
3535
}
3636

37+
define i64 @widen_assertzext_range_attr(ptr %x) nounwind {
38+
; CHECK-LABEL: widen_assertzext_range_attr:
39+
; CHECK: # %bb.0:
40+
; CHECK-NEXT: pushq %rax
41+
; CHECK-NEXT: callq test2@PLT
42+
; CHECK-NEXT: movb $127, %al
43+
; CHECK-NEXT: kmovw %eax, %k1
44+
; CHECK-NEXT: vpexpandq %zmm0, %zmm0 {%k1} {z}
45+
; CHECK-NEXT: vextracti32x4 $3, %zmm0, %xmm0
46+
; CHECK-NEXT: vmovq %xmm0, %rax
47+
; CHECK-NEXT: popq %rcx
48+
; CHECK-NEXT: vzeroupper
49+
; CHECK-NEXT: retq
50+
%e = call noundef range(i64 0, 2) <7 x i64> @test2()
51+
%d = extractelement <7 x i64> %e, i32 6
52+
ret i64 %d
53+
}
54+
3755
declare <16 x i64> @test()
3856
declare <7 x i64> @test2()
3957
!0 = !{ i64 0, i64 2 }

0 commit comments

Comments
 (0)