From f48f178717927e77c42ef17de42688b8a60733e3 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sun, 12 Feb 2023 06:56:43 -0500 Subject: [PATCH] [InstCombine] canonicalize cmp+select as smin/smax (V == SMIN) ? SMIN+1 : V --> smax(V, SMIN+1) (V == SMAX) ? SMAX-1 : V --> smin(V, SMAX-1) https://alive2.llvm.org/ce/z/d5bqjy Follow-up for the unsigned variants added with: 86b4d8645fc1b866 issue #60374 --- llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp | 8 +++++++- llvm/test/Transforms/InstCombine/select.ll | 8 +++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp index 894b11c..cefd0ac 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -1605,12 +1605,18 @@ static Value *foldSelectInstWithICmpConst(SelectInst &SI, ICmpInst *ICI, Value *TVal = SI.getTrueValue(); Value *FVal = SI.getFalseValue(); if (Pred == ICmpInst::ICMP_EQ && V == FVal) { - // (V == 0) ? 1 : V --> umax(V, 1) + // (V == UMIN) ? UMIN+1 : V --> umax(V, UMIN+1) if (CmpC->isMinValue() && match(TVal, m_SpecificInt(*CmpC + 1))) return Builder.CreateBinaryIntrinsic(Intrinsic::umax, V, TVal); // (V == UMAX) ? UMAX-1 : V --> umin(V, UMAX-1) if (CmpC->isMaxValue() && match(TVal, m_SpecificInt(*CmpC - 1))) return Builder.CreateBinaryIntrinsic(Intrinsic::umin, V, TVal); + // (V == SMIN) ? SMIN+1 : V --> smax(V, SMIN+1) + if (CmpC->isMinSignedValue() && match(TVal, m_SpecificInt(*CmpC + 1))) + return Builder.CreateBinaryIntrinsic(Intrinsic::smax, V, TVal); + // (V == SMAX) ? SMAX-1 : V --> smin(V, SMAX-1) + if (CmpC->isMaxSignedValue() && match(TVal, m_SpecificInt(*CmpC - 1))) + return Builder.CreateBinaryIntrinsic(Intrinsic::smin, V, TVal); } BinaryOperator *BO; diff --git a/llvm/test/Transforms/InstCombine/select.ll b/llvm/test/Transforms/InstCombine/select.ll index ab38bd1..20e9a3a 100644 --- a/llvm/test/Transforms/InstCombine/select.ll +++ b/llvm/test/Transforms/InstCombine/select.ll @@ -3484,8 +3484,7 @@ define i8 @not_clamp_umax2(i8 %x) { define i8 @clamp_smin(i8 %x) { ; CHECK-LABEL: @clamp_smin( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128 -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -127, i8 [[X]] +; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X:%.*]], i8 -127) ; CHECK-NEXT: ret i8 [[SEL]] ; %cmp = icmp eq i8 %x, -128 @@ -3497,7 +3496,7 @@ define i8 @clamp_smin_use(i8 %x) { ; CHECK-LABEL: @clamp_smin_use( ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8 [[X:%.*]], -128 ; CHECK-NEXT: call void @use1(i1 [[CMP]]) -; CHECK-NEXT: [[SEL:%.*]] = select i1 [[CMP]], i8 -127, i8 [[X]] +; CHECK-NEXT: [[SEL:%.*]] = call i8 @llvm.smax.i8(i8 [[X]], i8 -127) ; CHECK-NEXT: ret i8 [[SEL]] ; %cmp = icmp eq i8 %x, -128 @@ -3534,8 +3533,7 @@ define i8 @not_clamp_smin2(i8 %x) { define <2 x i8> @clamp_smaxval(<2 x i8> %x) { ; CHECK-LABEL: @clamp_smaxval( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq <2 x i8> [[X:%.*]], -; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[CMP]], <2 x i8> , <2 x i8> [[X]] +; CHECK-NEXT: [[SEL:%.*]] = call <2 x i8> @llvm.smin.v2i8(<2 x i8> [[X:%.*]], <2 x i8> ) ; CHECK-NEXT: ret <2 x i8> [[SEL]] ; %cmp = icmp eq <2 x i8> %x, -- 2.7.4