From: Sanjay Patel Date: Sat, 15 Aug 2015 17:01:54 +0000 (+0000) Subject: [x86] enable machine combiner reassociations for scalar single-precision minimums X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=8e0b9c201b144f759b371d82e5669c053e9743b9 [x86] enable machine combiner reassociations for scalar single-precision minimums git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245166 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86InstrInfo.cpp b/lib/Target/X86/X86InstrInfo.cpp index c2ff9109b3a..bd3a3e5165d 100644 --- a/lib/Target/X86/X86InstrInfo.cpp +++ b/lib/Target/X86/X86InstrInfo.cpp @@ -6385,11 +6385,17 @@ static bool hasReassociableSibling(const MachineInstr &Inst, bool &Commuted) { // TODO: There are many more machine instruction opcodes to match: // 1. Other data types (integer, vectors) // 2. Other math / logic operations (and, or) +// 3. Other forms of the same operation (intrinsics and other variants) static bool isAssociativeAndCommutative(const MachineInstr &Inst) { switch (Inst.getOpcode()) { case X86::IMUL16rr: case X86::IMUL32rr: case X86::IMUL64rr: + // Normal min/max instructions are not commutative because of NaN and signed + // zero semantics, but these are. Thus, there's no need to check for global + // relaxed math; the instructions themselves have the properties we need. + case X86::MINCSSrr: + case X86::VMINCSSrr: return true; case X86::ADDPDrr: case X86::ADDPSrr: diff --git a/test/CodeGen/X86/machine-combiner.ll b/test/CodeGen/X86/machine-combiner.ll index 900a43f55d3..3b5e6d212e3 100644 --- a/test/CodeGen/X86/machine-combiner.ll +++ b/test/CodeGen/X86/machine-combiner.ll @@ -358,21 +358,21 @@ define <4 x double> @reassociate_muls_v4f64(<4 x double> %x0, <4 x double> %x1, ret <4 x double> %t2 } -; TODO: Verify that SSE and AVX scalar single-precision minimum ops are reassociated. +; Verify that SSE and AVX scalar single-precision minimum ops are reassociated. define float @reassociate_mins_single(float %x0, float %x1, float %x2, float %x3) { ; SSE-LABEL: reassociate_mins_single: ; SSE: # BB#0: ; SSE-NEXT: divss %xmm1, %xmm0 +; SSE-NEXT: minss %xmm3, %xmm2 ; SSE-NEXT: minss %xmm2, %xmm0 -; SSE-NEXT: minss %xmm3, %xmm0 ; SSE-NEXT: retq ; ; AVX-LABEL: reassociate_mins_single: ; AVX: # BB#0: ; AVX-NEXT: vdivss %xmm1, %xmm0, %xmm0 -; AVX-NEXT: vminss %xmm0, %xmm2, %xmm0 -; AVX-NEXT: vminss %xmm0, %xmm3, %xmm0 +; AVX-NEXT: vminss %xmm3, %xmm2, %xmm1 +; AVX-NEXT: vminss %xmm1, %xmm0, %xmm0 ; AVX-NEXT: retq %t0 = fdiv float %x0, %x1 %cmp1 = fcmp olt float %x2, %t0