diff options
author | Sanjay Patel <spatel@rotateright.com> | 2018-12-16 15:05:48 +0000 |
---|---|---|
committer | Sanjay Patel <spatel@rotateright.com> | 2018-12-16 15:05:48 +0000 |
commit | 13ac2f15b0416bf85f53753657dafda6da4c353f (patch) | |
tree | ac51cff70412f13b0f68350405a23c8e2a3e4207 /llvm/lib/Target | |
parent | f24900b9348343f6c415bc164b0745e912e671a5 (diff) | |
download | bcm5719-llvm-13ac2f15b0416bf85f53753657dafda6da4c353f.tar.gz bcm5719-llvm-13ac2f15b0416bf85f53753657dafda6da4c353f.zip |
[x86] increment/decrement constant vector with min/max in vsetcc lowering (PR39859)
This is part of fixing PR39859:
https://bugs.llvm.org/show_bug.cgi?id=39859
We have a crippled vector ISA, so we have to invert a typical fold and create min/max here.
As discussed in the bug report, we can probably do better by using saturating subtract when
it's available, but we should have this improvement for the min/max patterns regardless.
Alive proofs:
https://rise4fun.com/Alive/zsf
https://rise4fun.com/Alive/Qrl
Differential Revision: https://reviews.llvm.org/D55515
llvm-svn: 349304
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 19 |
1 files changed, 16 insertions, 3 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index ed6700f4279..704b62d0ca9 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -19383,13 +19383,26 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget &Subtarget, bool FlipSigns = ISD::isUnsignedIntSetCC(Cond) && !(DAG.SignBitIsZero(Op0) && DAG.SignBitIsZero(Op1)); - // Special case: Use min/max operations for unsigned compares. We only want - // to do this for unsigned compares if we need to flip signs or if it allows - // use to avoid an invert. + // Special case: Use min/max operations for unsigned compares. const TargetLowering &TLI = DAG.getTargetLoweringInfo(); if (ISD::isUnsignedIntSetCC(Cond) && (FlipSigns || ISD::isTrueWhenEqual(Cond)) && TLI.isOperationLegal(ISD::UMIN, VT)) { + // If we have a constant operand, increment/decrement it and change the + // condition to avoid an invert. + // TODO: This could be extended to handle a non-splat constant by checking + // that each element of the constant is not the max/null value. + APInt C; + if (Cond == ISD::SETUGT && isConstantSplat(Op1, C) && !C.isMaxValue()) { + // X > C --> X >= (C+1) --> X == umax(X, C+1) + Op1 = DAG.getConstant(C + 1, dl, VT); + Cond = ISD::SETUGE; + } + if (Cond == ISD::SETULT && isConstantSplat(Op1, C) && !C.isNullValue()) { + // X < C --> X <= (C-1) --> X == umin(X, C-1) + Op1 = DAG.getConstant(C - 1, dl, VT); + Cond = ISD::SETULE; + } bool Invert = false; unsigned Opc; switch (Cond) { |