From 8b960d22ad4bc724b89e17f9ab0be9e6a468dd53 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Sat, 12 Sep 2015 19:47:50 +0000 Subject: [PATCH] [x86] enable machine combiner reassociations for 128-bit vector logical integer insts (2nd try) The changes in: test/CodeGen/X86/machine-cp.ll are just due to scheduling differences after some logic instructions were reassociated. llvm-svn: 247516 --- llvm/lib/Target/X86/X86InstrInfo.cpp | 6 ++ llvm/test/CodeGen/X86/machine-combiner-int-vec.ll | 68 +++++++++++++++++++++++ llvm/test/CodeGen/X86/machine-cp.ll | 18 +++--- 3 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 llvm/test/CodeGen/X86/machine-combiner-int-vec.ll diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 8b88316..446d4bc 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -6408,6 +6408,12 @@ static bool isAssociativeAndCommutative(const MachineInstr &Inst) { case X86::IMUL16rr: case X86::IMUL32rr: case X86::IMUL64rr: + case X86::PANDrr: + case X86::PORrr: + case X86::PXORrr: + case X86::VPANDrr: + case X86::VPORrr: + case X86::VPXORrr: // 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. diff --git a/llvm/test/CodeGen/X86/machine-combiner-int-vec.ll b/llvm/test/CodeGen/X86/machine-combiner-int-vec.ll new file mode 100644 index 0000000..8316f66 --- /dev/null +++ b/llvm/test/CodeGen/X86/machine-combiner-int-vec.ll @@ -0,0 +1,68 @@ +; RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=sse < %s | FileCheck %s --check-prefix=SSE +; RUN: llc -mtriple=x86_64-unknown-unknown -mcpu=x86-64 -mattr=avx < %s | FileCheck %s --check-prefix=AVX + +; Verify that 128-bit vector logical ops are reassociated. + +define <4 x i32> @reassociate_and_v4i32(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %x2, <4 x i32> %x3) { +; SSE-LABEL: reassociate_and_v4i32: +; SSE: # BB#0: +; SSE-NEXT: paddd %xmm1, %xmm0 +; SSE-NEXT: pand %xmm3, %xmm2 +; SSE-NEXT: pand %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: reassociate_and_v4i32: +; AVX: # BB#0: +; AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX-NEXT: vpand %xmm3, %xmm2, %xmm1 +; AVX-NEXT: vpand %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + + %t0 = add <4 x i32> %x0, %x1 + %t1 = and <4 x i32> %x2, %t0 + %t2 = and <4 x i32> %x3, %t1 + ret <4 x i32> %t2 +} + +define <4 x i32> @reassociate_or_v4i32(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %x2, <4 x i32> %x3) { +; SSE-LABEL: reassociate_or_v4i32: +; SSE: # BB#0: +; SSE-NEXT: paddd %xmm1, %xmm0 +; SSE-NEXT: por %xmm3, %xmm2 +; SSE-NEXT: por %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: reassociate_or_v4i32: +; AVX: # BB#0: +; AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX-NEXT: vpor %xmm3, %xmm2, %xmm1 +; AVX-NEXT: vpor %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + + %t0 = add <4 x i32> %x0, %x1 + %t1 = or <4 x i32> %x2, %t0 + %t2 = or <4 x i32> %x3, %t1 + ret <4 x i32> %t2 +} + +define <4 x i32> @reassociate_xor_v4i32(<4 x i32> %x0, <4 x i32> %x1, <4 x i32> %x2, <4 x i32> %x3) { +; SSE-LABEL: reassociate_xor_v4i32: +; SSE: # BB#0: +; SSE-NEXT: paddd %xmm1, %xmm0 +; SSE-NEXT: pxor %xmm3, %xmm2 +; SSE-NEXT: pxor %xmm2, %xmm0 +; SSE-NEXT: retq +; +; AVX-LABEL: reassociate_xor_v4i32: +; AVX: # BB#0: +; AVX-NEXT: vpaddd %xmm1, %xmm0, %xmm0 +; AVX-NEXT: vpxor %xmm3, %xmm2, %xmm1 +; AVX-NEXT: vpxor %xmm1, %xmm0, %xmm0 +; AVX-NEXT: retq + + %t0 = add <4 x i32> %x0, %x1 + %t1 = xor <4 x i32> %x2, %t0 + %t2 = xor <4 x i32> %x3, %t1 + ret <4 x i32> %t2 +} + diff --git a/llvm/test/CodeGen/X86/machine-cp.ll b/llvm/test/CodeGen/X86/machine-cp.ll index 768b9ca..d3b305b 100644 --- a/llvm/test/CodeGen/X86/machine-cp.ll +++ b/llvm/test/CodeGen/X86/machine-cp.ll @@ -73,22 +73,18 @@ while.end: ; preds = %while.body, %entry ; Machine propagation used to delete the first copy as the ; first few uses were . ; CHECK-NEXT: movdqa [[SRC]], [[CPY1:%xmm[0-9]+]] -; CHECK-NEXT: movdqa [[SRC]], [[CPY2:%xmm[0-9]+]] -; CHECK-NEXT: punpckhbw [[SRC]], -; Check that CPY1 is not redefined. -; CHECK-NOT: , [[CPY1]] -; undef use, we do not care. -; CHECK: punpcklwd [[CPY1]], -; Check that CPY1 is not redefined. -; CHECK-NOT: , [[CPY1]] +; CHECK: punpcklbw [[CPY1]], [[CPY1]] +; CHECK-NEXT: punpcklwd [[CPY1]], [[CPY1]] +; CHECK-NEXT: pslld $31, [[CPY1]] +; CHECK: movdqa [[SRC]], [[CPY2:%xmm[0-9]+]] ; CHECK: punpcklbw [[CPY2]], [[CPY2]] ; CHECK-NEXT: punpckhwd [[CPY2]], [[CPY2]] ; CHECK-NEXT: pslld $31, [[CPY2]] +; CHECK: punpckhbw [[SRC]], ; Check that CPY1 is not redefined. ; CHECK-NOT: , [[CPY1]] -; CHECK: punpcklbw [[CPY1]], [[CPY1]] -; CHECK-NEXT: punpcklwd [[CPY1]], [[CPY1]] -; CHECK-NEXT: pslld $31, [[CPY1]] +; undef use, we do not care. +; CHECK: punpcklwd [[CPY1]], define <16 x float> @foo(<16 x float> %x) { bb: %v3 = icmp slt <16 x i32> undef, zeroinitializer -- 2.7.4