[llvm] [ValueTracking] Handle trunc to i1 as condition in dominating condition. (PR #126414)
Andreas Jonson via llvm-commits
llvm-commits at lists.llvm.org
Sun Feb 9 04:59:37 PST 2025
https://github.com/andjo403 updated https://github.com/llvm/llvm-project/pull/126414
>From d148f62ef96724f38d4f4e370ba69c51055fa0d6 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 | 19 ++++++++++
.../test/Transforms/InstCombine/known-bits.ll | 36 +++++++------------
2 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/llvm/lib/Analysis/ValueTracking.cpp b/llvm/lib/Analysis/ValueTracking.cpp
index 8a9ad55366ee703..40fae7ca95d774b 100644
--- a/llvm/lib/Analysis/ValueTracking.cpp
+++ b/llvm/lib/Analysis/ValueTracking.cpp
@@ -801,6 +801,22 @@ static void computeKnownBitsFromCond(const Value *V, Value *Cond,
if (auto *Cmp = dyn_cast<ICmpInst>(Cond))
computeKnownBitsFromICmpCond(V, Cmp, Known, SQ, Invert);
+
+ if (match(Cond, m_Not(m_Value(Cond))))
+ Invert = !Invert;
+
+ 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()));
+ else
+ Known = Known.unionWith(DstKnown.anyext(Known.getBitWidth()));
+ }
}
void llvm::computeKnownBitsFromContext(const Value *V, KnownBits &Known,
@@ -10272,6 +10288,9 @@ void llvm::findValuesAffectedByCondition(
m_Value()))) {
// Handle patterns that computeKnownFPClass() support.
AddAffected(A);
+ } else if (!IsAssume && match(V, m_CombineOr(m_Trunc(m_Value(X)),
+ m_Not(m_Trunc(m_Value(X)))))) {
+ AddAffected(X);
}
}
}
diff --git a/llvm/test/Transforms/InstCombine/known-bits.ll b/llvm/test/Transforms/InstCombine/known-bits.ll
index 5b36684d7149b28..ac1ffa4bbde6f3c 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