[llvm] [LVI] Handle range attributes (PR #86413)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Sat Mar 23 14:37:40 PDT 2024
https://github.com/andjo403 created https://github.com/llvm/llvm-project/pull/86413
There is also a check of the range metadata at line 1120 but after https://github.com/llvm/llvm-project/pull/75311 there is no test that cover that line any more and I have not been able to create a test that trigger that code.
>From 875963ba43b5c0075c574bb9243d3c1a1299735e Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sat, 23 Mar 2024 22:21:47 +0100
Subject: [PATCH 1/2] [LVI] Add test for range attributes
---
.../CorrelatedValuePropagation/range.ll | 89 ++++++++++++++++---
1 file changed, 78 insertions(+), 11 deletions(-)
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
index cc66cbe7fce612..9c0feb55705aef 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
@@ -102,9 +102,9 @@ if.end8:
define i32 @test4(i32 %c) nounwind {
; CHECK-LABEL: @test4(
; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
-; CHECK-NEXT: i32 1, label [[SW_BB:%.*]]
-; CHECK-NEXT: i32 2, label [[SW_BB]]
-; CHECK-NEXT: i32 4, label [[SW_BB]]
+; CHECK-NEXT: i32 1, label [[SW_BB:%.*]]
+; CHECK-NEXT: i32 2, label [[SW_BB]]
+; CHECK-NEXT: i32 4, label [[SW_BB]]
; CHECK-NEXT: ]
; CHECK: sw.bb:
; CHECK-NEXT: br i1 true, label [[IF_THEN:%.*]], label [[IF_END:%.*]]
@@ -207,8 +207,8 @@ define i1 @test7(i32 %c) nounwind {
; CHECK-LABEL: @test7(
; CHECK-NEXT: entry:
; CHECK-NEXT: switch i32 [[C:%.*]], label [[SW_DEFAULT:%.*]] [
-; CHECK-NEXT: i32 6, label [[SW_BB:%.*]]
-; CHECK-NEXT: i32 7, label [[SW_BB]]
+; CHECK-NEXT: i32 6, label [[SW_BB:%.*]]
+; CHECK-NEXT: i32 7, label [[SW_BB]]
; CHECK-NEXT: ]
; CHECK: sw.bb:
; CHECK-NEXT: ret i1 true
@@ -790,8 +790,8 @@ define i32 @test18(i8 %a) {
; CHECK-NEXT: br label [[DISPATCH:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: switch i8 [[A]], label [[DISPATCH]] [
-; CHECK-NEXT: i8 93, label [[TARGET93:%.*]]
-; CHECK-NEXT: i8 -111, label [[DISPATCH]]
+; CHECK-NEXT: i8 93, label [[TARGET93:%.*]]
+; CHECK-NEXT: i8 -111, label [[DISPATCH]]
; CHECK-NEXT: ]
; CHECK: target93:
; CHECK-NEXT: ret i32 93
@@ -817,8 +817,8 @@ define i8 @test19(i8 %a) {
; CHECK-NEXT: br label [[DISPATCH:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: switch i8 [[A]], label [[DISPATCH]] [
-; CHECK-NEXT: i8 93, label [[TARGET93:%.*]]
-; CHECK-NEXT: i8 -111, label [[DISPATCH]]
+; CHECK-NEXT: i8 93, label [[TARGET93:%.*]]
+; CHECK-NEXT: i8 -111, label [[DISPATCH]]
; CHECK-NEXT: ]
; CHECK: target93:
; CHECK-NEXT: ret i8 96
@@ -846,8 +846,8 @@ define i1 @test20(i64 %a) {
; CHECK-NEXT: br label [[DISPATCH:%.*]]
; CHECK: dispatch:
; CHECK-NEXT: switch i64 [[A]], label [[DEFAULT:%.*]] [
-; CHECK-NEXT: i64 0, label [[EXIT2:%.*]]
-; CHECK-NEXT: i64 -2147483647, label [[EXIT2]]
+; CHECK-NEXT: i64 0, label [[EXIT2:%.*]]
+; CHECK-NEXT: i64 -2147483647, label [[EXIT2]]
; CHECK-NEXT: ]
; CHECK: default:
; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[B]], 0
@@ -1123,6 +1123,73 @@ else:
ret i1 true
}
+define i1 @icmp_eq_range_attr(i8 range(i8 1, 0) %i) {
+; CHECK-LABEL: @icmp_eq_range_attr(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I:%.*]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %cmp = icmp eq i8 %i, 0
+ ret i1 %cmp
+}
+
+define i1 @neg_icmp_eq_range_attr(i8 range(i8 -1, 1) %i) {
+; CHECK-LABEL: @neg_icmp_eq_range_attr(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I:%.*]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %cmp = icmp eq i8 %i, 0
+ ret i1 %cmp
+}
+
+declare range(i8 1, 0) i8 @returns_non_zero_range_helper()
+declare range(i8 -1, 1) i8 @returns_contain_zero_range_helper()
+
+define i1 @icmp_eq_range_return() {
+; CHECK-LABEL: @icmp_eq_range_return(
+; CHECK-NEXT: [[I:%.*]] = call i8 @returns_non_zero_range_helper()
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %i = call i8 @returns_non_zero_range_helper()
+ %cmp = icmp eq i8 %i, 0
+ ret i1 %cmp
+}
+
+define i1 @neg_icmp_eq_range_return() {
+; CHECK-LABEL: @neg_icmp_eq_range_return(
+; CHECK-NEXT: [[I:%.*]] = call i8 @returns_contain_zero_range_helper()
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %i = call i8 @returns_contain_zero_range_helper()
+ %cmp = icmp eq i8 %i, 0
+ ret i1 %cmp
+}
+
+declare i8 @returns_i8_helper()
+
+define i1 @icmp_eq_range_call() {
+; CHECK-LABEL: @icmp_eq_range_call(
+; CHECK-NEXT: [[I:%.*]] = call range(i8 1, 0) i8 @returns_i8_helper()
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %i = call range(i8 1, 0) i8 @returns_i8_helper()
+ %cmp = icmp eq i8 %i, 0
+ ret i1 %cmp
+}
+
+define i1 @neg_icmp_eq_range_call() {
+; CHECK-LABEL: @neg_icmp_eq_range_call(
+; CHECK-NEXT: [[I:%.*]] = call range(i8 0, 11) i8 @returns_i8_helper()
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0
+; CHECK-NEXT: ret i1 [[CMP]]
+;
+ %i = call range(i8 0, 11) i8 @returns_i8_helper()
+ %cmp = icmp eq i8 %i, 0
+ ret i1 %cmp
+}
+
declare i16 @llvm.ctlz.i16(i16, i1)
declare i16 @llvm.cttz.i16(i16, i1)
declare i16 @llvm.ctpop.i16(i16)
>From cdebd6933cb40a781a4ecf17f49dc73ed4518660 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sat, 23 Mar 2024 22:23:28 +0100
Subject: [PATCH 2/2] [LVI] Handle range attributes
---
llvm/lib/Analysis/LazyValueInfo.cpp | 10 +++++++---
.../Transforms/CorrelatedValuePropagation/range.ll | 9 +++------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 9ae31d165235ca..2504eb712e88d9 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -589,9 +589,12 @@ LazyValueInfoImpl::getBlockValue(Value *Val, BasicBlock *BB,
static ValueLatticeElement getFromRangeMetadata(Instruction *BBI) {
switch (BBI->getOpcode()) {
default: break;
- case Instruction::Load:
case Instruction::Call:
case Instruction::Invoke:
+ if (std::optional<ConstantRange> Range = cast<CallBase>(BBI)->getRange())
+ return ValueLatticeElement::getRange(*Range);
+ [[fallthrough]];
+ case Instruction::Load:
if (MDNode *Ranges = BBI->getMetadata(LLVMContext::MD_range))
if (isa<IntegerType>(BBI->getType())) {
return ValueLatticeElement::getRange(
@@ -706,10 +709,11 @@ std::optional<ValueLatticeElement>
LazyValueInfoImpl::solveBlockValueNonLocal(Value *Val, BasicBlock *BB) {
ValueLatticeElement Result; // Start Undefined.
- // If this is the entry block, we must be asking about an argument. The
- // value is overdefined.
+ // If this is the entry block, we must be asking about an argument.
if (BB->isEntryBlock()) {
assert(isa<Argument>(Val) && "Unknown live-in to the entry block");
+ if (std::optional<ConstantRange> Range = cast<Argument>(Val)->getRange())
+ return ValueLatticeElement::getRange(*Range);
return ValueLatticeElement::getOverdefined();
}
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
index 9c0feb55705aef..ce1b591218d1b1 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/range.ll
@@ -1125,8 +1125,7 @@ else:
define i1 @icmp_eq_range_attr(i8 range(i8 1, 0) %i) {
; CHECK-LABEL: @icmp_eq_range_attr(
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I:%.*]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%cmp = icmp eq i8 %i, 0
ret i1 %cmp
@@ -1147,8 +1146,7 @@ declare range(i8 -1, 1) i8 @returns_contain_zero_range_helper()
define i1 @icmp_eq_range_return() {
; CHECK-LABEL: @icmp_eq_range_return(
; CHECK-NEXT: [[I:%.*]] = call i8 @returns_non_zero_range_helper()
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%i = call i8 @returns_non_zero_range_helper()
%cmp = icmp eq i8 %i, 0
@@ -1171,8 +1169,7 @@ declare i8 @returns_i8_helper()
define i1 @icmp_eq_range_call() {
; CHECK-LABEL: @icmp_eq_range_call(
; CHECK-NEXT: [[I:%.*]] = call range(i8 1, 0) i8 @returns_i8_helper()
-; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[I]], 0
-; CHECK-NEXT: ret i1 [[CMP]]
+; CHECK-NEXT: ret i1 false
;
%i = call range(i8 1, 0) i8 @returns_i8_helper()
%cmp = icmp eq i8 %i, 0
More information about the llvm-commits
mailing list