From: Sanjay Patel Date: Fri, 5 Nov 2021 20:40:02 +0000 (-0400) Subject: [InstCombine] add tests for umax with sub; NFC X-Git-Tag: upstream/15.0.7~26554 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=025a2f73a31955cfd9b1e097533b9c6ef15dc6d3;p=platform%2Fupstream%2Fllvm.git [InstCombine] add tests for umax with sub; NFC --- diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 07a2ac8..7888712 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -9575,6 +9575,23 @@ static SDValue foldVSelectToSignBitSplatMask(SDNode *N, SelectionDAG &DAG) { return DAG.getNode(ISD::OR, DL, VT, Sra, N2); } + // If the comparison is testing for a positive value, we have to invert + // the sign bit mask, so only do that transform if the target has a bitwise + // 'and not' instruction (the invert is free). + // (Cond0 s> -1) ? N1 : 0 --> ~(Cond0 s>> BW-1) & N1 + const TargetLowering &TLI = DAG.getTargetLoweringInfo(); + if (CC == ISD::SETGT && isAllOnesOrAllOnesSplat(Cond1) && + isNullOrNullSplat(N2) && TLI.hasAndNot(N2)) { + SDLoc DL(N); + SDValue ShiftAmt = DAG.getConstant(VT.getScalarSizeInBits() - 1, DL, VT); + SDValue Sra = DAG.getNode(ISD::SRA, DL, VT, Cond0, ShiftAmt); + SDValue Not = DAG.getNOT(DL, Sra, VT); + return DAG.getNode(ISD::AND, DL, VT, Not, N1); + } + // (X > 0) ? X : 0 <-- This is canonical signed max. +// if (!(isAllOnesConstant(N1) || (isNullConstant(N1) && N0 == N2))) +// return SDValue(); + return SDValue(); } diff --git a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll index 7b76c3ad..573ed8e 100644 --- a/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll +++ b/llvm/test/Transforms/InstCombine/minmax-intrinsics.ll @@ -2129,3 +2129,27 @@ define <3 x i8> @umax_vector_splat_undef(<3 x i8> %x) { %r = call <3 x i8> @llvm.umax.v3i8(<3 x i8> %a, <3 x i8> ) ret <3 x i8> %r } + +define <3 x i8> @umax_sub_vec(<3 x i8> %x, <3 x i8> %y) { +; CHECK-LABEL: @umax_sub_vec( +; CHECK-NEXT: [[U:%.*]] = call <3 x i8> @llvm.umax.v3i8(<3 x i8> [[X:%.*]], <3 x i8> [[Y:%.*]]) +; CHECK-NEXT: [[R:%.*]] = sub <3 x i8> [[U]], [[Y]] +; CHECK-NEXT: ret <3 x i8> [[R]] +; + %u = call <3 x i8> @llvm.umax.v3i8(<3 x i8> %x, <3 x i8> %y) + %r = sub <3 x i8> %u, %y + ret <3 x i8> %r +} + +define i8 @umax_sub_use(i8 %x, i8 %y) { +; CHECK-LABEL: @umax_sub_use( +; CHECK-NEXT: [[U:%.*]] = call i8 @llvm.umax.i8(i8 [[X:%.*]], i8 [[Y:%.*]]) +; CHECK-NEXT: call void @use(i8 [[U]]) +; CHECK-NEXT: [[R:%.*]] = sub i8 [[U]], [[Y]] +; CHECK-NEXT: ret i8 [[R]] +; + %u = call i8 @llvm.umax.i8(i8 %x, i8 %y) + call void @use(i8 %u) + %r = sub i8 %u, %y + ret i8 %r +}