[llvm] [LVI] Add trunc to i1 handling. (PR #124480)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 26 13:58:07 PST 2025
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/124480
>From 2947c0aab7cd8ee8d7ea462e73ffbe53716e09f7 Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Sun, 26 Jan 2025 22:57:50 +0100
Subject: [PATCH] [LVI] Add trunc to i1 handling.
---
llvm/lib/Analysis/LazyValueInfo.cpp | 19 ++++++
.../CorrelatedValuePropagation/icmp.ll | 60 ++-----------------
2 files changed, 23 insertions(+), 56 deletions(-)
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 20f69a0955f51c..05c66457fdaa3e 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);
+ std::optional<ValueLatticeElement>
+ getValueFromTrunc(Value *Val, TruncInst *Trunc, bool IsTrueDest);
std::optional<ValueLatticeElement>
getValueFromCondition(Value *Val, Value *Cond, bool IsTrueDest,
@@ -1283,6 +1285,20 @@ std::optional<ValueLatticeElement> LazyValueInfoImpl::getValueFromICmpCondition(
return ValueLatticeElement::getOverdefined();
}
+std::optional<ValueLatticeElement>
+LazyValueInfoImpl::getValueFromTrunc(Value *Val, TruncInst *Trunc,
+ bool IsTrueDest) {
+ assert(Trunc->getType()->isIntegerTy(1));
+
+ Type *Ty = Val->getType();
+ if (!Ty->isIntegerTy() || Trunc->getOperand(0) != Val)
+ return ValueLatticeElement::getOverdefined();
+
+ 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 +1328,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/icmp.ll b/llvm/test/Transforms/CorrelatedValuePropagation/icmp.ll
index e4de34c339d2de..d83cbf68004e88 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: ret void
; CHECK: if.false:
; CHECK-NEXT: ret void
@@ -1543,10 +1541,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: ret void
; CHECK: if.false:
; CHECK-NEXT: ret void
@@ -1565,51 +1561,3 @@ if.true:
if.false:
ret void
}
-
-define void @test_icmp_trunc(i8 %a) {
-; CHECK-LABEL: @test_icmp_trunc(
-; CHECK-NEXT: [[CMP1:%.*]] = icmp ne i8 [[A:%.*]], 0
-; CHECK-NEXT: br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
-; CHECK: if.true:
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[A]] to i1
-; CHECK-NEXT: call void @check1(i1 [[TRUNC]])
-; CHECK-NEXT: ret void
-; CHECK: if.false:
-; CHECK-NEXT: ret void
-;
- %cmp1 = icmp ne i8 %a, 0
- br i1 %cmp1, label %if.true, label %if.false
-
-if.true:
- %trunc = trunc i8 %a to i1
- call void @check1(i1 %trunc)
- ret void
-
-if.false:
- ret void
-}
-
-define void @test_icmp_trunc_not(i8 %a) {
-; CHECK-LABEL: @test_icmp_trunc_not(
-; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 [[A:%.*]], -1
-; CHECK-NEXT: br i1 [[CMP1]], label [[IF_TRUE:%.*]], label [[IF_FALSE:%.*]]
-; CHECK: if.true:
-; CHECK-NEXT: [[TRUNC:%.*]] = trunc i8 [[A]] to i1
-; CHECK-NEXT: [[NOT:%.*]] = xor i1 [[TRUNC]], true
-; CHECK-NEXT: call void @check1(i1 [[TRUNC]])
-; CHECK-NEXT: ret void
-; CHECK: if.false:
-; CHECK-NEXT: ret void
-;
- %cmp1 = icmp eq i8 %a, -1
- br i1 %cmp1, label %if.true, label %if.false
-
-if.true:
- %trunc = trunc i8 %a to i1
- %not = xor i1 %trunc, true
- call void @check1(i1 %trunc)
- ret void
-
-if.false:
- ret void
-}
More information about the llvm-commits
mailing list