[llvm] [InstCombine] Fix pointer replacement in `foldSelectValueEquivalence` (PR #161701)
Yingwei Zheng via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 2 10:09:30 PDT 2025
https://github.com/dtcxzyw created https://github.com/llvm/llvm-project/pull/161701
Closes https://github.com/llvm/llvm-project/issues/161636.
Compile-time impact (+0.02%): https://llvm-compile-time-tracker.com/compare.php?from=17f6888d1771c9f61378a0a58725f3359277ddda&to=44cdcb84b1a9d996cd61f2c37ac4c9df5bc531af&stat=instructions%3Au
I used to disable this fold for pointers, because I cannot construct a positive test that is covered by `foldSelectValueEquivalence ` but not covered by `simplifySelectWithICmpCond`. But the IR diff shows we still benefit from the fold in InstCombine:
+ Bail out on pointers: https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2880
+ This patch: https://github.com/dtcxzyw/llvm-opt-benchmark/pull/2882
Perhaps we can cache the query result of `getUnderlyingObjectAggressive` to improve the compile time.
>From 33495201d22773f8f7b26181222686a025c5a74f Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 2 Oct 2025 20:40:54 +0800
Subject: [PATCH 1/2] [InstCombine] Add pre-commit tests. NFC.
---
.../test/Transforms/InstCombine/select-gep.ll | 26 +++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/llvm/test/Transforms/InstCombine/select-gep.ll b/llvm/test/Transforms/InstCombine/select-gep.ll
index dd8dffba11b05..7aba1421b9ad2 100644
--- a/llvm/test/Transforms/InstCombine/select-gep.ll
+++ b/llvm/test/Transforms/InstCombine/select-gep.ll
@@ -286,3 +286,29 @@ define <2 x ptr> @test7(<2 x ptr> %p1, i64 %idx, <2 x i1> %cc) {
%select = select <2 x i1> %cc, <2 x ptr> %p1, <2 x ptr> %gep
ret <2 x ptr> %select
}
+
+define ptr @ptr_eq_replace_freeze1(ptr %p, ptr %q) {
+; CHECK-LABEL: @ptr_eq_replace_freeze1(
+; CHECK-NEXT: [[Q_FR:%.*]] = freeze ptr [[Q:%.*]]
+; CHECK-NEXT: ret ptr [[Q_FR]]
+;
+ %p.fr = freeze ptr %p
+ %q.fr = freeze ptr %q
+ %cmp = icmp eq ptr %p.fr, %q.fr
+ %select = select i1 %cmp, ptr %p.fr, ptr %q.fr
+ ret ptr %select
+}
+
+define ptr @ptr_eq_replace_freeze2(ptr %p, ptr %q) {
+; CHECK-LABEL: @ptr_eq_replace_freeze2(
+; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P:%.*]]
+; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i8, ptr [[P_FR]], i64 16
+; CHECK-NEXT: ret ptr [[SELECT]]
+;
+ %gep1 = getelementptr i32, ptr %p, i64 4
+ %gep2 = getelementptr i32, ptr %q, i64 4
+ %cmp = icmp eq ptr %p, %q
+ %cmp.fr = freeze i1 %cmp
+ %select = select i1 %cmp.fr, ptr %gep1, ptr %gep2
+ ret ptr %select
+}
>From 18f21c6b5451e6bd54561586db9740e398615002 Mon Sep 17 00:00:00 2001
From: Yingwei Zheng <dtcxzyw2333 at gmail.com>
Date: Thu, 2 Oct 2025 20:50:24 +0800
Subject: [PATCH 2/2] [InstCombine] Fix pointer replacement in
`foldSelectValueEquivalence`
---
.../InstCombine/InstCombineSelect.cpp | 17 +++++++++++------
llvm/test/Transforms/InstCombine/select-gep.ll | 10 ++++++++--
2 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
index 87000a1c36eef..5ea79b92633d9 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp
@@ -17,6 +17,7 @@
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/CmpInstAnalysis.h"
#include "llvm/Analysis/InstructionSimplify.h"
+#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/OverflowInstAnalysis.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Analysis/VectorUtils.h"
@@ -1411,6 +1412,8 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
// in the cmp and in f(Y).
if (TrueVal == OldOp && (isa<Constant>(OldOp) || !isa<Constant>(NewOp)))
return nullptr;
+ if (!canReplacePointersIfEqual(OldOp, NewOp, DL))
+ return nullptr;
if (Value *V = simplifyWithOpReplaced(TrueVal, OldOp, NewOp, SQ,
/* AllowRefinement=*/true)) {
@@ -1466,12 +1469,14 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
// Example:
// (X == 42) ? 43 : (X + 1) --> (X == 42) ? (X + 1) : (X + 1) --> X + 1
SmallVector<Instruction *> DropFlags;
- if (simplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, SQ,
- /* AllowRefinement */ false,
- &DropFlags) == TrueVal ||
- simplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, SQ,
- /* AllowRefinement */ false,
- &DropFlags) == TrueVal) {
+ if ((canReplacePointersIfEqual(CmpLHS, CmpRHS, DL) &&
+ simplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, SQ,
+ /* AllowRefinement */ false,
+ &DropFlags) == TrueVal) ||
+ (canReplacePointersIfEqual(CmpRHS, CmpLHS, DL) &&
+ simplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, SQ,
+ /* AllowRefinement */ false,
+ &DropFlags) == TrueVal)) {
for (Instruction *I : DropFlags) {
I->dropPoisonGeneratingAnnotations();
Worklist.add(I);
diff --git a/llvm/test/Transforms/InstCombine/select-gep.ll b/llvm/test/Transforms/InstCombine/select-gep.ll
index 7aba1421b9ad2..718133699a8a7 100644
--- a/llvm/test/Transforms/InstCombine/select-gep.ll
+++ b/llvm/test/Transforms/InstCombine/select-gep.ll
@@ -290,7 +290,10 @@ define <2 x ptr> @test7(<2 x ptr> %p1, i64 %idx, <2 x i1> %cc) {
define ptr @ptr_eq_replace_freeze1(ptr %p, ptr %q) {
; CHECK-LABEL: @ptr_eq_replace_freeze1(
; CHECK-NEXT: [[Q_FR:%.*]] = freeze ptr [[Q:%.*]]
-; CHECK-NEXT: ret ptr [[Q_FR]]
+; CHECK-NEXT: [[Q_FR1:%.*]] = freeze ptr [[Q1:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[Q_FR]], [[Q_FR1]]
+; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[Q_FR]], ptr [[Q_FR1]]
+; CHECK-NEXT: ret ptr [[SELECT]]
;
%p.fr = freeze ptr %p
%q.fr = freeze ptr %q
@@ -302,7 +305,10 @@ define ptr @ptr_eq_replace_freeze1(ptr %p, ptr %q) {
define ptr @ptr_eq_replace_freeze2(ptr %p, ptr %q) {
; CHECK-LABEL: @ptr_eq_replace_freeze2(
; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P:%.*]]
-; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i8, ptr [[P_FR]], i64 16
+; CHECK-NEXT: [[P_FR1:%.*]] = freeze ptr [[P1:%.*]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P_FR1]], [[P_FR]]
+; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], ptr [[P_FR1]], ptr [[P_FR]]
+; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i8, ptr [[SELECT_V]], i64 16
; CHECK-NEXT: ret ptr [[SELECT]]
;
%gep1 = getelementptr i32, ptr %p, i64 4
More information about the llvm-commits
mailing list