[llvm] 8aebceb - [LVI] Add trunc to i1 handling. (#124480)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 2 10:45:53 PST 2025
Author: Andreas Jonson
Date: 2025-02-02T19:45:50+01:00
New Revision: 8aebcebd90b79b90eca828762fd3b0637e430e51
URL: https://github.com/llvm/llvm-project/commit/8aebcebd90b79b90eca828762fd3b0637e430e51
DIFF: https://github.com/llvm/llvm-project/commit/8aebcebd90b79b90eca828762fd3b0637e430e51.diff
LOG: [LVI] Add trunc to i1 handling. (#124480)
Proof: https://alive2.llvm.org/ce/z/yPrRp-
Added:
Modified:
llvm/lib/Analysis/LazyValueInfo.cpp
llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll
llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
Removed:
################################################################################
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 20f69a0955f51c..f588d8f7e7b109 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -398,6 +398,8 @@ class LazyValueInfoImpl {
std::optional<ValueLatticeElement>
getValueFromICmpCondition(Value *Val, ICmpInst *ICI, bool isTrueDest,
bool UseBlockValue);
+ ValueLatticeElement getValueFromTrunc(Value *Val, TruncInst *Trunc,
+ bool IsTrueDest);
std::optional<ValueLatticeElement>
getValueFromCondition(Value *Val, Value *Cond, bool IsTrueDest,
@@ -1283,6 +1285,27 @@ std::optional<ValueLatticeElement> LazyValueInfoImpl::getValueFromICmpCondition(
return ValueLatticeElement::getOverdefined();
}
+ValueLatticeElement LazyValueInfoImpl::getValueFromTrunc(Value *Val,
+ TruncInst *Trunc,
+ bool IsTrueDest) {
+ assert(Trunc->getType()->isIntOrIntVectorTy(1));
+
+ if (Trunc->getOperand(0) != Val)
+ return ValueLatticeElement::getOverdefined();
+
+ Type *Ty = Val->getType();
+
+ if (Trunc->hasNoUnsignedWrap()) {
+ if (IsTrueDest)
+ return ValueLatticeElement::get(ConstantInt::get(Ty, 1));
+ return ValueLatticeElement::get(Constant::getNullValue(Ty));
+ }
+
+ if (IsTrueDest)
+ return ValueLatticeElement::getNot(Constant::getNullValue(Ty));
+ return ValueLatticeElement::getNot(Constant::getAllOnesValue(Ty));
+}
+
// Handle conditions of the form
// extractvalue(op.with.overflow(%x, C), 1).
static ValueLatticeElement getValueFromOverflowCondition(
@@ -1312,6 +1335,9 @@ LazyValueInfoImpl::getValueFromCondition(Value *Val, Value *Cond,
if (ICmpInst *ICI = dyn_cast<ICmpInst>(Cond))
return getValueFromICmpCondition(Val, ICI, IsTrueDest, UseBlockValue);
+ if (auto *Trunc = dyn_cast<TruncInst>(Cond))
+ return getValueFromTrunc(Val, Trunc, IsTrueDest);
+
if (auto *EVI = dyn_cast<ExtractValueInst>(Cond))
if (auto *WO = dyn_cast<WithOverflowInst>(EVI->getAggregateOperand()))
if (EVI->getNumIndices() == 1 && *EVI->idx_begin() == 1)
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll b/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll
index dba15165ebee60..fa9323df4dff74 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/cond-at-use.ll
@@ -557,9 +557,8 @@ define i16 @and_elide(i16 noundef %x) {
define i16 @and_elide_trunc_cond(i16 noundef %x) {
; CHECK-LABEL: @and_elide_trunc_cond(
-; CHECK-NEXT: [[AND:%.*]] = and i16 [[X:%.*]], 1
-; CHECK-NEXT: [[CMP:%.*]] = trunc nuw i16 [[X]] to i1
-; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[AND]], i16 24
+; CHECK-NEXT: [[CMP:%.*]] = trunc nuw i16 [[X:%.*]] to i1
+; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i16 [[X]], i16 24
; CHECK-NEXT: ret i16 [[SEL]]
;
%and = and i16 %x, 1
@@ -570,9 +569,8 @@ define i16 @and_elide_trunc_cond(i16 noundef %x) {
define <2 x i8> @and_elide_trunc_cond_vec(<2 x i8> noundef %x) {
; CHECK-LABEL: @and_elide_trunc_cond_vec(
-; CHECK-NEXT: [[AND:%.*]] = and <2 x i8> [[X:%.*]], splat (i8 1)
-; CHECK-NEXT: [[CMP:%.*]] = trunc nuw <2 x i8> [[X]] to <2 x i1>
-; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[AND]], <2 x i8> splat (i8 24)
+; CHECK-NEXT: [[CMP:%.*]] = trunc nuw <2 x i8> [[X:%.*]] to <2 x i1>
+; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> [[X]], <2 x i8> splat (i8 24)
; CHECK-NEXT: ret <2 x i8> [[SEL]]
;
%and = and <2 x i8> %x, splat (i8 1)
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index c6579e5c1ac7db..5fa8f4e1b9f296 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
@@ -1515,10 +1515,8 @@ define void @test_trunc_bittest(i8 %a) {
; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[A:%.*]] to i1
; CHECK-NEXT: br i1 [[TRUNC]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.true:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], 0
-; CHECK-NEXT: call void @check1(i1 [[CMP1]])
-; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], 0
-; CHECK-NEXT: call void @check1(i1 [[CMP2]])
+; CHECK-NEXT: call void @check1(i1 true)
+; CHECK-NEXT: call void @check1(i1 false)
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i8 [[A]], 1
; CHECK-NEXT: call void @check1(i1 [[CMP3]])
; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[A]], 1
@@ -1559,10 +1557,8 @@ define void @test_trunc_not_bittest(i8 %a) {
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true
; CHECK-NEXT: br i1 [[NOT]], label [[IF_FALSE:%.*]], label [[IF_TRUE:%.*]]
; CHECK: if.true:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], -1
-; CHECK-NEXT: call void @check1(i1 [[CMP1]])
-; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], -1
-; CHECK-NEXT: call void @check1(i1 [[CMP2]])
+; CHECK-NEXT: call void @check1(i1 true)
+; CHECK-NEXT: call void @check1(i1 false)
; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i8 [[A]], 0
; CHECK-NEXT: call void @check1(i1 [[CMP3]])
; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[A]], 0
@@ -1603,14 +1599,10 @@ define void @test_trunc_nuw_bittest(i8 %a) {
; CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i8 [[A:%.*]] to i1
; CHECK-NEXT: br i1 [[TRUNC]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.true:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], 0
-; CHECK-NEXT: call void @check1(i1 [[CMP1]])
-; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], 0
-; CHECK-NEXT: call void @check1(i1 [[CMP2]])
-; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i8 [[A]], 1
-; CHECK-NEXT: call void @check1(i1 [[CMP3]])
-; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[A]], 1
-; CHECK-NEXT: call void @check1(i1 [[CMP4]])
+; CHECK-NEXT: call void @check1(i1 true)
+; CHECK-NEXT: call void @check1(i1 false)
+; CHECK-NEXT: call void @check1(i1 false)
+; CHECK-NEXT: call void @check1(i1 true)
; CHECK-NEXT: ret void
; CHECK: if.false:
; CHECK-NEXT: ret void
@@ -1639,14 +1631,10 @@ define void @test_trunc_nuw_not_bittest(i8 %a) {
; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true
; CHECK-NEXT: br i1 [[NOT]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
; CHECK: if.true:
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A]], 0
-; CHECK-NEXT: call void @check1(i1 [[CMP1]])
-; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i8 [[A]], 0
-; CHECK-NEXT: call void @check1(i1 [[CMP2]])
-; CHECK-NEXT: [[CMP3:%.*]] = icmp ne i8 [[A]], 1
-; CHECK-NEXT: call void @check1(i1 [[CMP3]])
-; CHECK-NEXT: [[CMP4:%.*]] = icmp eq i8 [[A]], 1
-; CHECK-NEXT: call void @check1(i1 [[CMP4]])
+; CHECK-NEXT: call void @check1(i1 false)
+; CHECK-NEXT: call void @check1(i1 true)
+; CHECK-NEXT: call void @check1(i1 true)
+; CHECK-NEXT: call void @check1(i1 false)
; CHECK-NEXT: ret void
; CHECK: if.false:
; CHECK-NEXT: ret void
More information about the llvm-commits
mailing list