[llvm] [GVN] Handle not in equality propagation (PR #151942)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 4 04:05:50 PDT 2025
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/151942
None
>From c4efaa633219f5f47402ea2c74a9c1b0a36ba82d Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 4 Aug 2025 13:01:56 +0200
Subject: [PATCH 1/2] [GVN] Add some tests for not condition propagation (NFC)
---
llvm/test/Transforms/GVN/condprop.ll | 82 ++++++++++++++++++++++++++++
1 file changed, 82 insertions(+)
diff --git a/llvm/test/Transforms/GVN/condprop.ll b/llvm/test/Transforms/GVN/condprop.ll
index 3babdd8173a21..27cbd41485bee 100644
--- a/llvm/test/Transforms/GVN/condprop.ll
+++ b/llvm/test/Transforms/GVN/condprop.ll
@@ -999,5 +999,87 @@ loop.latch:
br label %loop
}
+define i1 @not_cond(i1 %c) {
+; CHECK-LABEL: @not_cond(
+; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: br i1 [[C_NOT]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i1 [[C]]
+; CHECK: else:
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %c.not = xor i1 %c, true
+ br i1 %c.not, label %if, label %else
+
+if:
+ ret i1 %c
+
+else:
+ ret i1 %c
+}
+
+define i32 @not_cond_icmp(i32 %x) {
+; CHECK-LABEL: @not_cond_icmp(
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 42
+; CHECK-NEXT: [[CMP_NOT:%.*]] = xor i1 [[CMP]], true
+; CHECK-NEXT: br i1 [[CMP_NOT]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i32 [[X]]
+; CHECK: else:
+; CHECK-NEXT: ret i32 [[X]]
+;
+ %cmp = icmp eq i32 %x, 42
+ %cmp.not = xor i1 %cmp, true
+ br i1 %cmp.not, label %if, label %else
+
+if:
+ ret i32 %x
+
+else:
+ ret i32 %x
+}
+
+define i1 @not_cond_logic1(i1 %c, i1 %d) {
+; CHECK-LABEL: @not_cond_logic1(
+; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_NOT]], [[D:%.*]]
+; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i1 [[C]]
+; CHECK: else:
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %c.not = xor i1 %c, true
+ %and = and i1 %c.not, %d
+ br i1 %and, label %if, label %else
+
+if:
+ ret i1 %c
+
+else:
+ ret i1 %c
+}
+
+define i1 @not_cond_logic2(i1 %c, i1 %d) {
+; CHECK-LABEL: @not_cond_logic2(
+; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true
+; CHECK-NEXT: [[AND:%.*]] = or i1 [[C_NOT]], [[D:%.*]]
+; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
+; CHECK: if:
+; CHECK-NEXT: ret i1 [[C]]
+; CHECK: else:
+; CHECK-NEXT: ret i1 [[C]]
+;
+ %c.not = xor i1 %c, true
+ %or = or i1 %c.not, %d
+ br i1 %or, label %if, label %else
+
+if:
+ ret i1 %c
+
+else:
+ ret i1 %c
+}
+
declare void @use_bool(i1)
declare void @use_ptr(ptr)
>From c9e4be4ed30f44652b8d58e6a32c6f606ffe9a38 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Mon, 4 Aug 2025 13:04:37 +0200
Subject: [PATCH 2/2] [GVN] Handle not in equality propagation
---
llvm/lib/Transforms/Scalar/GVN.cpp | 5 +++++
llvm/test/Transforms/GVN/condprop.ll | 10 +++++-----
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index fa6ee95d33d10..3a73b42455b0d 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -2683,6 +2683,11 @@ bool GVNPass::propagateEquality(Value *LHS, Value *RHS,
Worklist.emplace_back(A, ConstantInt::get(A->getType(), IsKnownTrue));
continue;
}
+
+ if (match(LHS, m_Not(m_Value(A)))) {
+ Worklist.emplace_back(A, ConstantInt::get(A->getType(), !IsKnownTrue));
+ continue;
+ }
}
return Changed;
diff --git a/llvm/test/Transforms/GVN/condprop.ll b/llvm/test/Transforms/GVN/condprop.ll
index 27cbd41485bee..15ffcbff1e157 100644
--- a/llvm/test/Transforms/GVN/condprop.ll
+++ b/llvm/test/Transforms/GVN/condprop.ll
@@ -1004,9 +1004,9 @@ define i1 @not_cond(i1 %c) {
; CHECK-NEXT: [[C_NOT:%.*]] = xor i1 [[C:%.*]], true
; CHECK-NEXT: br i1 [[C_NOT]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 false
; CHECK: else:
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 true
;
%c.not = xor i1 %c, true
br i1 %c.not, label %if, label %else
@@ -1026,7 +1026,7 @@ define i32 @not_cond_icmp(i32 %x) {
; CHECK: if:
; CHECK-NEXT: ret i32 [[X]]
; CHECK: else:
-; CHECK-NEXT: ret i32 [[X]]
+; CHECK-NEXT: ret i32 42
;
%cmp = icmp eq i32 %x, 42
%cmp.not = xor i1 %cmp, true
@@ -1045,7 +1045,7 @@ define i1 @not_cond_logic1(i1 %c, i1 %d) {
; CHECK-NEXT: [[AND:%.*]] = and i1 [[C_NOT]], [[D:%.*]]
; CHECK-NEXT: br i1 [[AND]], label [[IF:%.*]], label [[ELSE:%.*]]
; CHECK: if:
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 false
; CHECK: else:
; CHECK-NEXT: ret i1 [[C]]
;
@@ -1068,7 +1068,7 @@ define i1 @not_cond_logic2(i1 %c, i1 %d) {
; CHECK: if:
; CHECK-NEXT: ret i1 [[C]]
; CHECK: else:
-; CHECK-NEXT: ret i1 [[C]]
+; CHECK-NEXT: ret i1 true
;
%c.not = xor i1 %c, true
%or = or i1 %c.not, %d
More information about the llvm-commits
mailing list