[llvm] [LVI] Remove support for SPF selects (PR #115305)
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 7 03:53:49 PST 2024
https://github.com/nikic created https://github.com/llvm/llvm-project/pull/115305
None
>From 6b88b7f1d2ffa2335f92530d70a8f1dc50b27e57 Mon Sep 17 00:00:00 2001
From: Nikita Popov <npopov at redhat.com>
Date: Thu, 7 Nov 2024 12:50:34 +0100
Subject: [PATCH] [LVI] Remove support for SPF selects
---
llvm/lib/Analysis/LazyValueInfo.cpp | 50 -------------------
.../CorrelatedValuePropagation/basic.ll | 44 ++++++++++------
.../do-not-handle-impossible-values.ll | 12 ++---
3 files changed, 32 insertions(+), 74 deletions(-)
diff --git a/llvm/lib/Analysis/LazyValueInfo.cpp b/llvm/lib/Analysis/LazyValueInfo.cpp
index 42b04046ce10d3..f0cb6604c60e36 100644
--- a/llvm/lib/Analysis/LazyValueInfo.cpp
+++ b/llvm/lib/Analysis/LazyValueInfo.cpp
@@ -804,56 +804,6 @@ LazyValueInfoImpl::solveBlockValueSelect(SelectInst *SI, BasicBlock *BB) {
return std::nullopt;
ValueLatticeElement &FalseVal = *OptFalseVal;
- if (TrueVal.isConstantRange() || FalseVal.isConstantRange()) {
- const ConstantRange &TrueCR = TrueVal.asConstantRange(SI->getType());
- const ConstantRange &FalseCR = FalseVal.asConstantRange(SI->getType());
- Value *LHS = nullptr;
- Value *RHS = nullptr;
- SelectPatternResult SPR = matchSelectPattern(SI, LHS, RHS);
- // Is this a min specifically of our two inputs? (Avoid the risk of
- // ValueTracking getting smarter looking back past our immediate inputs.)
- if (SelectPatternResult::isMinOrMax(SPR.Flavor) &&
- ((LHS == SI->getTrueValue() && RHS == SI->getFalseValue()) ||
- (RHS == SI->getTrueValue() && LHS == SI->getFalseValue()))) {
- ConstantRange ResultCR = [&]() {
- switch (SPR.Flavor) {
- default:
- llvm_unreachable("unexpected minmax type!");
- case SPF_SMIN: /// Signed minimum
- return TrueCR.smin(FalseCR);
- case SPF_UMIN: /// Unsigned minimum
- return TrueCR.umin(FalseCR);
- case SPF_SMAX: /// Signed maximum
- return TrueCR.smax(FalseCR);
- case SPF_UMAX: /// Unsigned maximum
- return TrueCR.umax(FalseCR);
- };
- }();
- return ValueLatticeElement::getRange(
- ResultCR, TrueVal.isConstantRangeIncludingUndef() ||
- FalseVal.isConstantRangeIncludingUndef());
- }
-
- if (SPR.Flavor == SPF_ABS) {
- if (LHS == SI->getTrueValue())
- return ValueLatticeElement::getRange(
- TrueCR.abs(), TrueVal.isConstantRangeIncludingUndef());
- if (LHS == SI->getFalseValue())
- return ValueLatticeElement::getRange(
- FalseCR.abs(), FalseVal.isConstantRangeIncludingUndef());
- }
-
- if (SPR.Flavor == SPF_NABS) {
- ConstantRange Zero(APInt::getZero(TrueCR.getBitWidth()));
- if (LHS == SI->getTrueValue())
- return ValueLatticeElement::getRange(
- Zero.sub(TrueCR.abs()), FalseVal.isConstantRangeIncludingUndef());
- if (LHS == SI->getFalseValue())
- return ValueLatticeElement::getRange(
- Zero.sub(FalseCR.abs()), FalseVal.isConstantRangeIncludingUndef());
- }
- }
-
// Can we constrain the facts about the true and false values by using the
// condition itself? This shows up with idioms like e.g. select(a > 5, a, 5).
// TODO: We could potentially refine an overdefined true value above.
diff --git a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
index 3c3b1d4bef45bb..f7cdd3c0036224 100644
--- a/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
+++ b/llvm/test/Transforms/CorrelatedValuePropagation/basic.ll
@@ -581,7 +581,8 @@ define i1 @umin(i32 %a, i32 %b) {
; CHECK: b_guard:
; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ult i32 [[A]], [[B]]
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MIN]], 7
+; CHECK-NEXT: ret i1 [[RES]]
; CHECK: out:
; CHECK-NEXT: ret i1 false
;
@@ -614,7 +615,8 @@ define i1 @smin(i32 %a, i32 %b) {
; CHECK: b_guard:
; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp ule i32 [[A]], [[B]]
; CHECK-NEXT: [[MIN:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MIN]], 7
+; CHECK-NEXT: ret i1 [[RES]]
; CHECK: out:
; CHECK-NEXT: ret i1 false
;
@@ -647,7 +649,8 @@ define i1 @smax(i32 %a, i32 %b) {
; CHECK: b_guard:
; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MAX]], 7
+; CHECK-NEXT: ret i1 [[RES]]
; CHECK: out:
; CHECK-NEXT: ret i1 false
;
@@ -680,7 +683,8 @@ define i1 @umax(i32 %a, i32 %b) {
; CHECK: b_guard:
; CHECK-NEXT: [[SEL_CMP:%.*]] = icmp uge i32 [[A]], [[B]]
; CHECK-NEXT: [[MAX:%.*]] = select i1 [[SEL_CMP]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT: ret i1 false
+; CHECK-NEXT: [[RES:%.*]] = icmp eq i32 [[MAX]], 7
+; CHECK-NEXT: ret i1 [[RES]]
; CHECK: out:
; CHECK-NEXT: ret i1 false
;
@@ -706,7 +710,8 @@ define i1 @umin_lhs_overdefined_rhs_const(i32 %a) {
; CHECK-SAME: (i32 [[A:%.*]]) {
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], 42
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 42
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[SEL]], 42
+; CHECK-NEXT: ret i1 [[CMP2]]
;
%cmp = icmp ult i32 %a, 42
%sel = select i1 %cmp, i32 %a, i32 42
@@ -719,7 +724,8 @@ define i1 @umin_rhs_overdefined_lhs_const(i32 %a) {
; CHECK-SAME: (i32 [[A:%.*]]) {
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A]], 42
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 42, i32 [[A]]
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ule i32 [[SEL]], 42
+; CHECK-NEXT: ret i1 [[CMP2]]
;
%cmp = icmp uge i32 %a, 42
%sel = select i1 %cmp, i32 42, i32 %a
@@ -734,7 +740,8 @@ define i1 @umin_lhs_overdefined_rhs_range(i32 %a, i32 %b) {
; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[A]], [[B]]
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[B]]
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[SEL]], 42
+; CHECK-NEXT: ret i1 [[CMP2]]
;
%assume = icmp ult i32 %b, 42
call void @llvm.assume(i1 %assume)
@@ -751,7 +758,8 @@ define i1 @umin_rhs_overdefined_lhs_range(i32 %a, i32 %b) {
; CHECK-NEXT: call void @llvm.assume(i1 [[ASSUME]])
; CHECK-NEXT: [[CMP:%.*]] = icmp uge i32 [[A]], [[B]]
; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i32 [[B]], i32 [[A]]
-; CHECK-NEXT: ret i1 true
+; CHECK-NEXT: [[CMP2:%.*]] = icmp ult i32 [[SEL]], 42
+; CHECK-NEXT: ret i1 [[CMP2]]
;
%assume = icmp ult i32 %b, 42
call void @llvm.assume(i1 %assume)
@@ -1085,10 +1093,11 @@ define void @abs1(i32 %a, ptr %p) {
; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[A]], 0
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[SUB]], i32 [[A]]
; CHECK-NEXT: store i1 true, ptr [[P]], align 1
-; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[ABS]], 19
+; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[ABS]], 19
; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
-; CHECK-NEXT: store i1 true, ptr [[P]], align 1
-; CHECK-NEXT: [[C4:%.*]] = icmp uge i32 [[ABS]], 1
+; CHECK-NEXT: [[C3:%.*]] = icmp sge i32 [[ABS]], 0
+; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
+; CHECK-NEXT: [[C4:%.*]] = icmp sge i32 [[ABS]], 1
; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
@@ -1131,10 +1140,11 @@ define void @abs2(i32 %a, ptr %p) {
; CHECK-NEXT: [[CMP:%.*]] = icmp sge i32 [[A]], 0
; CHECK-NEXT: [[ABS:%.*]] = select i1 [[CMP]], i32 [[A]], i32 [[SUB]]
; CHECK-NEXT: store i1 true, ptr [[P]], align 1
-; CHECK-NEXT: [[C2:%.*]] = icmp ult i32 [[ABS]], 19
+; CHECK-NEXT: [[C2:%.*]] = icmp slt i32 [[ABS]], 19
; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
-; CHECK-NEXT: store i1 true, ptr [[P]], align 1
-; CHECK-NEXT: [[C4:%.*]] = icmp uge i32 [[ABS]], 1
+; CHECK-NEXT: [[C3:%.*]] = icmp sge i32 [[ABS]], 0
+; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
+; CHECK-NEXT: [[C4:%.*]] = icmp sge i32 [[ABS]], 1
; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
; CHECK-NEXT: br label [[EXIT]]
; CHECK: exit:
@@ -1179,7 +1189,8 @@ define void @nabs1(i32 %a, ptr %p) {
; CHECK-NEXT: store i1 true, ptr [[P]], align 1
; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
-; CHECK-NEXT: store i1 true, ptr [[P]], align 1
+; CHECK-NEXT: [[C3:%.*]] = icmp sle i32 [[NABS]], 0
+; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1
; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
; CHECK-NEXT: br label [[EXIT]]
@@ -1225,7 +1236,8 @@ define void @nabs2(i32 %a, ptr %p) {
; CHECK-NEXT: store i1 true, ptr [[P]], align 1
; CHECK-NEXT: [[C2:%.*]] = icmp sgt i32 [[NABS]], -19
; CHECK-NEXT: store i1 [[C2]], ptr [[P]], align 1
-; CHECK-NEXT: store i1 true, ptr [[P]], align 1
+; CHECK-NEXT: [[C3:%.*]] = icmp sle i32 [[NABS]], 0
+; CHECK-NEXT: store i1 [[C3]], ptr [[P]], align 1
; CHECK-NEXT: [[C4:%.*]] = icmp sle i32 [[NABS]], -1
; CHECK-NEXT: store i1 [[C4]], ptr [[P]], align 1
; CHECK-NEXT: br label [[EXIT]]
diff --git a/llvm/test/Transforms/LowerSwitch/do-not-handle-impossible-values.ll b/llvm/test/Transforms/LowerSwitch/do-not-handle-impossible-values.ll
index 64ef5829890669..b806e1282b1671 100644
--- a/llvm/test/Transforms/LowerSwitch/do-not-handle-impossible-values.ll
+++ b/llvm/test/Transforms/LowerSwitch/do-not-handle-impossible-values.ll
@@ -801,10 +801,8 @@ define i32 @test16(float %f) {
; CHECK-LABEL: @test16(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[I:%.*]] = fptosi float [[F:%.*]] to i64
-; CHECK-NEXT: [[COND_LEFT:%.*]] = icmp slt i64 [[I]], 0
-; CHECK-NEXT: [[CLAMP_LEFT:%.*]] = select i1 [[COND_LEFT]], i64 0, i64 [[I]]
-; CHECK-NEXT: [[COND_RIGHT:%.*]] = icmp sgt i64 [[I]], 3
-; CHECK-NEXT: [[CLAMP:%.*]] = select i1 [[COND_RIGHT]], i64 3, i64 [[CLAMP_LEFT]]
+; CHECK-NEXT: [[CLAMP_LEFT:%.*]] = call i64 @llvm.smax.i64(i64 [[I]], i64 0)
+; CHECK-NEXT: [[CLAMP:%.*]] = call i64 @llvm.smin.i64(i64 [[CLAMP_LEFT]], i64 3)
; CHECK-NEXT: br label [[LEAFBLOCK:%.*]]
; CHECK: LeafBlock:
; CHECK-NEXT: [[SWITCHLEAF:%.*]] = icmp sge i64 [[CLAMP]], 2
@@ -821,10 +819,8 @@ define i32 @test16(float %f) {
;
entry:
%i = fptosi float %f to i64
- %cond.left = icmp slt i64 %i, 0
- %clamp.left = select i1 %cond.left, i64 0, i64 %i
- %cond.right = icmp sgt i64 %i, 3
- %clamp = select i1 %cond.right, i64 3, i64 %clamp.left
+ %clamp.left = call i64 @llvm.smax(i64 %i, i64 0)
+ %clamp = call i64 @llvm.smin(i64 %clamp.left, i64 3)
switch i64 %clamp, label %case.D [
i64 0, label %case.1
i64 1, label %case.1
More information about the llvm-commits
mailing list