diff options
author | Duncan Sands <baldrick@free.fr> | 2011-09-17 16:49:39 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2011-09-17 16:49:39 +0000 |
commit | 6bcd2196e5febb97efe188d0d6de403c577d96fc (patch) | |
tree | b147a99b1f7f3b65365ba8535f8466ab53f5d766 | |
parent | 2c693dc1261d8b8d92b5c96cf00ec873dde86bb2 (diff) | |
download | llvm-6bcd2196e5febb97efe188d0d6de403c577d96fc.tar.gz llvm-6bcd2196e5febb97efe188d0d6de403c577d96fc.tar.bz2 llvm-6bcd2196e5febb97efe188d0d6de403c577d96fc.tar.xz |
Synthesize x86 max/min instructions also for vectors (i.e. produce
maxps and maxpd). This broke the sse41-blend.ll testcase by causing
maxpd to be produced rather than a cmp+blend pair, which is the reason
I tweaked it. Gives a small speedup on doduc with dragonegg when the
GCC vectorizer is used.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139986 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 11 | ||||
-rw-r--r-- | test/CodeGen/X86/sse-minmax.ll | 38 | ||||
-rw-r--r-- | test/CodeGen/X86/sse41-blend.ll | 8 |
3 files changed, 46 insertions, 11 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index d279e04729..42193c41cb 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1129,6 +1129,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) setTargetDAGCombine(ISD::VECTOR_SHUFFLE); setTargetDAGCombine(ISD::EXTRACT_VECTOR_ELT); setTargetDAGCombine(ISD::BUILD_VECTOR); + setTargetDAGCombine(ISD::VSELECT); setTargetDAGCombine(ISD::SELECT); setTargetDAGCombine(ISD::SHL); setTargetDAGCombine(ISD::SRA); @@ -12551,7 +12552,8 @@ static SDValue PerformEXTRACT_VECTOR_ELTCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); } -/// PerformSELECTCombine - Do target-specific dag combines on SELECT nodes. +/// PerformSELECTCombine - Do target-specific dag combines on SELECT and VSELECT +/// nodes. static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, const X86Subtarget *Subtarget) { DebugLoc DL = N->getDebugLoc(); @@ -12564,9 +12566,9 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, // instructions match the semantics of the common C idiom x<y?x:y but not // x<=y?x:y, because of how they handle negative zero (which can be // ignored in unsafe-math mode). - if (Subtarget->hasXMMInt() && - (LHS.getValueType() == MVT::f32 || LHS.getValueType() == MVT::f64) && - Cond.getOpcode() == ISD::SETCC) { + if (Subtarget->hasXMMInt() && Cond.getOpcode() == ISD::SETCC && + (LHS.getValueType() == MVT::f32 || LHS.getValueType() == MVT::f64 || + LHS.getValueType() == MVT::v4f32 || LHS.getValueType() == MVT::v2f64)) { ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get(); unsigned Opcode = 0; @@ -13871,6 +13873,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N, default: break; case ISD::EXTRACT_VECTOR_ELT: return PerformEXTRACT_VECTOR_ELTCombine(N, DAG, *this); + case ISD::VSELECT: case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget); case X86ISD::CMOV: return PerformCMOVCombine(N, DAG, DCI); case ISD::ADD: return OptimizeConditionalInDecrement(N, DAG); diff --git a/test/CodeGen/X86/sse-minmax.ll b/test/CodeGen/X86/sse-minmax.ll index ff0af25ce2..af1a73b8f1 100644 --- a/test/CodeGen/X86/sse-minmax.ll +++ b/test/CodeGen/X86/sse-minmax.ll @@ -1,6 +1,6 @@ -; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs | FileCheck %s -; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -enable-unsafe-fp-math -enable-no-nans-fp-math | FileCheck -check-prefix=UNSAFE %s -; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -enable-no-nans-fp-math | FileCheck -check-prefix=FINITE %s +; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -promote-elements | FileCheck %s +; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -enable-unsafe-fp-math -enable-no-nans-fp-math -promote-elements | FileCheck -check-prefix=UNSAFE %s +; RUN: llc < %s -march=x86-64 -asm-verbose=false -join-physregs -enable-no-nans-fp-math -promote-elements | FileCheck -check-prefix=FINITE %s ; Some of these patterns can be matched as SSE min or max. Some of ; then can be matched provided that the operands are swapped. @@ -933,3 +933,35 @@ entry: %x_addr.0 = select i1 %0, double 3.000000e+03, double %x ; <double> [#uses=1] ret double %x_addr.0 } + +; UNSAFE: maxpd: +; UNSAFE: maxpd +define <2 x double> @maxpd(<2 x double> %x, <2 x double> %y) { + %max_is_x = fcmp oge <2 x double> %x, %y + %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y + ret <2 x double> %max +} + +; UNSAFE: minpd: +; UNSAFE: minpd +define <2 x double> @minpd(<2 x double> %x, <2 x double> %y) { + %min_is_x = fcmp ole <2 x double> %x, %y + %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y + ret <2 x double> %min +} + +; UNSAFE: maxps: +; UNSAFE: maxps +define <4 x float> @maxps(<4 x float> %x, <4 x float> %y) { + %max_is_x = fcmp oge <4 x float> %x, %y + %max = select <4 x i1> %max_is_x, <4 x float> %x, <4 x float> %y + ret <4 x float> %max +} + +; UNSAFE: minps: +; UNSAFE: minps +define <4 x float> @minps(<4 x float> %x, <4 x float> %y) { + %min_is_x = fcmp ole <4 x float> %x, %y + %min = select <4 x i1> %min_is_x, <4 x float> %x, <4 x float> %y + ret <4 x float> %min +} diff --git a/test/CodeGen/X86/sse41-blend.ll b/test/CodeGen/X86/sse41-blend.ll index a21416b7a8..78604a0e96 100644 --- a/test/CodeGen/X86/sse41-blend.ll +++ b/test/CodeGen/X86/sse41-blend.ll @@ -73,10 +73,10 @@ define <2 x double> @A(<2 x double> %x, <2 x double> %y) { ; CHECK: B define <2 x double> @B(<2 x double> %x, <2 x double> %y) { - ; CHECK: cmpltpd + ; CHECK: cmpnlepd ; CHECK: blendvpd - %max_is_x = fcmp ogt <2 x double> %x, %y - %max = select <2 x i1> %max_is_x, <2 x double> %x, <2 x double> %y - ret <2 x double> %max + %min_is_x = fcmp ult <2 x double> %x, %y + %min = select <2 x i1> %min_is_x, <2 x double> %x, <2 x double> %y + ret <2 x double> %min } |