[llvm] [ValueTracking] Handle trunc to i1 as condition in dominating condition. (PR #126414)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Mon Feb 10 10:33:40 PST 2025
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/126414
>From 167513c0ccc59e490829a33a5de69e4911b5789c Mon Sep 17 00:00:00 2001
From: Andreas Jonson <andjo403 at hotmail.com>
Date: Wed, 5 Feb 2025 21:29:03 +0100
Subject: [PATCH] [ValueTracking] Handle trunc to i1 as condition in dominating
condition.
---
llvm/lib/Analysis/ValueTracking.cpp | 24 ++++++++++++-
.../test/Transforms/InstCombine/known-bits.ll | 36 +++++++------------
2 files changed, 35 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index fb744d61aad63d5..28d7e1ce401e406 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -797,10 +797,28 @@ static void computeKnownBitsFromCond(const Value *V, Value *Cond,
else
Known2 = Known2.intersectWith(Known3);
Known = Known.unionWith(Known2);
+ return;
}
- if (auto *Cmp = dyn_cast<ICmpInst>(Cond))
+ if (auto *Cmp = dyn_cast<ICmpInst>(Cond)) {
computeKnownBitsFromICmpCond(V, Cmp, Known, SQ, Invert);
+ return;
+ }
+
+ if (match(Cond, m_Trunc(m_Specific(V)))) {
+ KnownBits DstKnown(1);
+ if (Invert) {
+ DstKnown.setAllZero();
+ } else {
+ DstKnown.setAllOnes();
+ }
+ if (cast<TruncInst>(Cond)->hasNoUnsignedWrap()) {
+ Known = Known.unionWith(DstKnown.zext(Known.getBitWidth()));
+ return;
+ }
+ Known = Known.unionWith(DstKnown.anyext(Known.getBitWidth()));
+ return;
+ }
if (Depth < MaxAnalysisRecursionDepth && match(Cond, m_Not(m_Value(A))))
computeKnownBitsFromCond(V, A, Known, Depth + 1, SQ, !Invert);
@@ -10280,6 +10298,10 @@ void llvm::findValuesAffectedByCondition(
m_Value()))) {
// Handle patterns that computeKnownFPClass() support.
AddAffected(A);
+ } else if (!IsAssume && match(V, m_Trunc(m_Value(X)))) {
+ // Assume is checked here as X is already added above for assumes in
+ // addValueAffectedByCondition
+ AddAffected(X);
} else if (!IsAssume && match(V, m_Not(m_Value(X)))) {
// Assume is checked here to avoid issues with ephemeral values
Worklist.push_back(X);
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index b729cbd971accce..9a9fec694ff0e4d 100644
--- a/llvm/test/Transforms/InstCombine/known-bits.ll
+++ b/llvm/test/Transforms/InstCombine/known-bits.ll
@@ -2167,11 +2167,9 @@ define i8 @test_trunc_and_1(i8 %a) {
; CHECK-NEXT: [[CAST:%.*]] = trunc i8 [[A:%.*]] to i1
; CHECK-NEXT: br i1 [[CAST]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[B:%.*]] = and i8 [[A]], 1
-; CHECK-NEXT: ret i8 [[B]]
+; CHECK-NEXT: ret i8 1
; CHECK: if.else:
-; CHECK-NEXT: [[C:%.*]] = and i8 [[A]], 1
-; CHECK-NEXT: ret i8 [[C]]
+; CHECK-NEXT: ret i8 0
;
entry:
%cast = trunc i8 %a to i1
@@ -2192,11 +2190,9 @@ define i8 @test_not_trunc_and_1(i8 %a) {
; CHECK-NEXT: [[CAST:%.*]] = trunc i8 [[A:%.*]] to i1
; CHECK-NEXT: br i1 [[CAST]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[B:%.*]] = and i8 [[A]], 1
-; CHECK-NEXT: ret i8 [[B]]
+; CHECK-NEXT: ret i8 0
; CHECK: if.else:
-; CHECK-NEXT: [[C:%.*]] = and i8 [[A]], 1
-; CHECK-NEXT: ret i8 [[C]]
+; CHECK-NEXT: ret i8 1
;
entry:
%cast = trunc i8 %a to i1
@@ -2243,11 +2239,9 @@ define i8 @test_trunc_nuw_and_1(i8 %a) {
; CHECK-NEXT: [[CAST:%.*]] = trunc nuw i8 [[A:%.*]] to i1
; CHECK-NEXT: br i1 [[CAST]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[B:%.*]] = and i8 [[A]], 1
-; CHECK-NEXT: ret i8 [[B]]
+; CHECK-NEXT: ret i8 0
; CHECK: if.else:
-; CHECK-NEXT: [[C:%.*]] = and i8 [[A]], 1
-; CHECK-NEXT: ret i8 [[C]]
+; CHECK-NEXT: ret i8 1
;
entry:
%cast = trunc nuw i8 %a to i1
@@ -2268,11 +2262,9 @@ define i8 @test_trunc_nuw_or_2(i8 %a) {
; CHECK-NEXT: [[CAST:%.*]] = trunc nuw i8 [[A:%.*]] to i1
; CHECK-NEXT: br i1 [[CAST]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[B:%.*]] = or i8 [[A]], 2
-; CHECK-NEXT: ret i8 [[B]]
+; CHECK-NEXT: ret i8 2
; CHECK: if.else:
-; CHECK-NEXT: [[C:%.*]] = or i8 [[A]], 2
-; CHECK-NEXT: ret i8 [[C]]
+; CHECK-NEXT: ret i8 3
;
entry:
%cast = trunc nuw i8 %a to i1
@@ -2293,11 +2285,9 @@ define i8 @test_not_trunc_nuw_and_1(i8 %a) {
; CHECK-NEXT: [[CAST:%.*]] = trunc nuw i8 [[A:%.*]] to i1
; CHECK-NEXT: br i1 [[CAST]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
; CHECK: if.then:
-; CHECK-NEXT: [[B:%.*]] = and i8 [[A]], 1
-; CHECK-NEXT: ret i8 [[B]]
+; CHECK-NEXT: ret i8 0
; CHECK: if.else:
-; CHECK-NEXT: [[C:%.*]] = and i8 [[A]], 1
-; CHECK-NEXT: ret i8 [[C]]
+; CHECK-NEXT: ret i8 1
;
entry:
%cast = trunc nuw i8 %a to i1
@@ -2319,8 +2309,7 @@ define i8 @test_trunc_cond_and(i8 %x, i1 %c) {
; CHECK-NEXT: [[COND:%.*]] = and i1 [[C:%.*]], [[CMP]]
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
-; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -2
-; CHECK-NEXT: ret i8 [[OR1]]
+; CHECK-NEXT: ret i8 -1
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -2
; CHECK-NEXT: ret i8 [[OR2]]
@@ -2345,8 +2334,7 @@ define i8 @test_not_trunc_cond_and(i8 %x, i1 %c) {
; CHECK-NEXT: [[COND:%.*]] = and i1 [[C:%.*]], [[NOT]]
; CHECK-NEXT: br i1 [[COND]], label [[IF:%.*]], label [[EXIT:%.*]]
; CHECK: if:
-; CHECK-NEXT: [[OR1:%.*]] = or i8 [[X]], -2
-; CHECK-NEXT: ret i8 [[OR1]]
+; CHECK-NEXT: ret i8 -2
; CHECK: exit:
; CHECK-NEXT: [[OR2:%.*]] = or i8 [[X]], -2
; CHECK-NEXT: ret i8 [[OR2]]
More information about the llvm-commits
mailing list