Skip to content

Commit 73a351e

Browse files
authored
[llvm][GVN] Propagate trunc nuw to i1 equalities (#143273)
This patch adds to GVN's `propagateEquality()` to reason about equality constraints through `trunc nuw iN to i1`. Given: %tr = trunc nuw iN %v to i1 We can deduce that if `%tr == true`, then `%v == 1`, and if `%tr == false`, then `%v == 0`. This is valid because `nuw` guarantees that truncation didn't lose unsigned bits, so `%v` must have been either 0 or 1. The patch adds logic to propagate this information via the GVN worklist. This enables further simplification opportunities downstream, such as folding redundant stores or conditionals that depend on `%v`. Includes a test case in `GVN/trunc-nuw-equality.ll`. Resolves #142744
1 parent 8a5c8eb commit 73a351e

File tree

2 files changed

+36
-0
lines changed

2 files changed

+36
-0
lines changed

llvm/lib/Transforms/Scalar/GVN.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2579,6 +2579,14 @@ bool GVNPass::propagateEquality(Value *LHS, Value *RHS,
25792579

25802580
continue;
25812581
}
2582+
2583+
// Propagate equalities that results from truncation with no unsigned wrap
2584+
// like (trunc nuw i64 %v to i1) == "true" or (trunc nuw i64 %v to i1) ==
2585+
// "false"
2586+
if (match(LHS, m_NUWTrunc(m_Value(A)))) {
2587+
Worklist.emplace_back(A, ConstantInt::get(A->getType(), IsKnownTrue));
2588+
continue;
2589+
}
25822590
}
25832591

25842592
return Changed;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt -passes=gvn -S < %s | FileCheck %s
3+
4+
define void @test(ptr %p, i64 %v) {
5+
; CHECK-LABEL: define void @test(
6+
; CHECK-SAME: ptr [[P:%.*]], i64 [[V:%.*]]) {
7+
; CHECK-NEXT: [[ENTRY:.*:]]
8+
; CHECK-NEXT: [[TR:%.*]] = trunc nuw i64 [[V]] to i1
9+
; CHECK-NEXT: br i1 [[TR]], label %[[RET:.*]], label %[[STORE:.*]]
10+
; CHECK: [[STORE]]:
11+
; CHECK-NEXT: store i64 0, ptr [[P]], align 4
12+
; CHECK-NEXT: ret void
13+
; CHECK: [[RET]]:
14+
; CHECK-NEXT: store i64 1, ptr [[P]], align 4
15+
; CHECK-NEXT: ret void
16+
;
17+
entry:
18+
%tr = trunc nuw i64 %v to i1
19+
br i1 %tr, label %ret, label %store
20+
21+
store:
22+
store i64 %v, ptr %p
23+
ret void
24+
25+
ret:
26+
store i64 %v, ptr %p
27+
ret void
28+
}

0 commit comments

Comments
 (0)