Skip to content

Commit c41611b

Browse files
authored
[InstCombine] Fix pointer replacement in foldSelectValueEquivalence (#161701)
Closes #161636. Compile-time impact (+0.06%): https://llvm-compile-time-tracker.com/compare.php?from=c2ef022aa7413ddc9aba48fa6fbe6fbd0cb14e19&to=9a0f0302efc30580136d191e66bac929f08ee25f&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: dtcxzyw/llvm-opt-benchmark#2880 + This patch: dtcxzyw/llvm-opt-benchmark#2882
1 parent 92d8313 commit c41611b

File tree

2 files changed

+52
-10
lines changed

2 files changed

+52
-10
lines changed

llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "llvm/Analysis/AssumptionCache.h"
1818
#include "llvm/Analysis/CmpInstAnalysis.h"
1919
#include "llvm/Analysis/InstructionSimplify.h"
20+
#include "llvm/Analysis/Loads.h"
2021
#include "llvm/Analysis/OverflowInstAnalysis.h"
2122
#include "llvm/Analysis/ValueTracking.h"
2223
#include "llvm/Analysis/VectorUtils.h"
@@ -42,6 +43,7 @@
4243
#include "llvm/Support/KnownBits.h"
4344
#include "llvm/Transforms/InstCombine/InstCombiner.h"
4445
#include <cassert>
46+
#include <optional>
4547
#include <utility>
4648

4749
#define DEBUG_TYPE "instcombine"
@@ -1451,10 +1453,16 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
14511453
return nullptr;
14521454
};
14531455

1454-
if (Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1455-
return R;
1456-
if (Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1457-
return R;
1456+
bool CanReplaceCmpLHSWithRHS = canReplacePointersIfEqual(CmpLHS, CmpRHS, DL);
1457+
if (CanReplaceCmpLHSWithRHS) {
1458+
if (Instruction *R = ReplaceOldOpWithNewOp(CmpLHS, CmpRHS))
1459+
return R;
1460+
}
1461+
bool CanReplaceCmpRHSWithLHS = canReplacePointersIfEqual(CmpRHS, CmpLHS, DL);
1462+
if (CanReplaceCmpRHSWithLHS) {
1463+
if (Instruction *R = ReplaceOldOpWithNewOp(CmpRHS, CmpLHS))
1464+
return R;
1465+
}
14581466

14591467
auto *FalseInst = dyn_cast<Instruction>(FalseVal);
14601468
if (!FalseInst)
@@ -1469,12 +1477,14 @@ Instruction *InstCombinerImpl::foldSelectValueEquivalence(SelectInst &Sel,
14691477
// Example:
14701478
// (X == 42) ? 43 : (X + 1) --> (X == 42) ? (X + 1) : (X + 1) --> X + 1
14711479
SmallVector<Instruction *> DropFlags;
1472-
if (simplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, SQ,
1473-
/* AllowRefinement */ false,
1474-
&DropFlags) == TrueVal ||
1475-
simplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, SQ,
1476-
/* AllowRefinement */ false,
1477-
&DropFlags) == TrueVal) {
1480+
if ((CanReplaceCmpLHSWithRHS &&
1481+
simplifyWithOpReplaced(FalseVal, CmpLHS, CmpRHS, SQ,
1482+
/* AllowRefinement */ false,
1483+
&DropFlags) == TrueVal) ||
1484+
(CanReplaceCmpRHSWithLHS &&
1485+
simplifyWithOpReplaced(FalseVal, CmpRHS, CmpLHS, SQ,
1486+
/* AllowRefinement */ false,
1487+
&DropFlags) == TrueVal)) {
14781488
for (Instruction *I : DropFlags) {
14791489
I->dropPoisonGeneratingAnnotations();
14801490
Worklist.add(I);

llvm/test/Transforms/InstCombine/select-gep.ll

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,3 +286,35 @@ define <2 x ptr> @test7(<2 x ptr> %p1, i64 %idx, <2 x i1> %cc) {
286286
%select = select <2 x i1> %cc, <2 x ptr> %p1, <2 x ptr> %gep
287287
ret <2 x ptr> %select
288288
}
289+
290+
define ptr @ptr_eq_replace_freeze1(ptr %p, ptr %q) {
291+
; CHECK-LABEL: @ptr_eq_replace_freeze1(
292+
; CHECK-NEXT: [[Q_FR:%.*]] = freeze ptr [[Q:%.*]]
293+
; CHECK-NEXT: [[Q_FR1:%.*]] = freeze ptr [[Q1:%.*]]
294+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[Q_FR]], [[Q_FR1]]
295+
; CHECK-NEXT: [[SELECT:%.*]] = select i1 [[CMP]], ptr [[Q_FR]], ptr [[Q_FR1]]
296+
; CHECK-NEXT: ret ptr [[SELECT]]
297+
;
298+
%p.fr = freeze ptr %p
299+
%q.fr = freeze ptr %q
300+
%cmp = icmp eq ptr %p.fr, %q.fr
301+
%select = select i1 %cmp, ptr %p.fr, ptr %q.fr
302+
ret ptr %select
303+
}
304+
305+
define ptr @ptr_eq_replace_freeze2(ptr %p, ptr %q) {
306+
; CHECK-LABEL: @ptr_eq_replace_freeze2(
307+
; CHECK-NEXT: [[P_FR:%.*]] = freeze ptr [[P:%.*]]
308+
; CHECK-NEXT: [[P_FR1:%.*]] = freeze ptr [[P1:%.*]]
309+
; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr [[P_FR1]], [[P_FR]]
310+
; CHECK-NEXT: [[SELECT_V:%.*]] = select i1 [[CMP]], ptr [[P_FR1]], ptr [[P_FR]]
311+
; CHECK-NEXT: [[SELECT:%.*]] = getelementptr i8, ptr [[SELECT_V]], i64 16
312+
; CHECK-NEXT: ret ptr [[SELECT]]
313+
;
314+
%gep1 = getelementptr i32, ptr %p, i64 4
315+
%gep2 = getelementptr i32, ptr %q, i64 4
316+
%cmp = icmp eq ptr %p, %q
317+
%cmp.fr = freeze i1 %cmp
318+
%select = select i1 %cmp.fr, ptr %gep1, ptr %gep2
319+
ret ptr %select
320+
}

0 commit comments

Comments
 (0)