From 413ec947a97034eae25a6a104d66c43515a247c6 Mon Sep 17 00:00:00 2001 From: Sanjay Patel Date: Mon, 23 Sep 2019 13:30:23 +0000 Subject: [PATCH] [x86] fix assert with horizontal math + broadcast of vector (PR43402) https://bugs.llvm.org/show_bug.cgi?id=43402 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@372606 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/X86/X86ISelLowering.cpp | 8 ++++---- lib/Target/X86/X86ISelLowering.h | 3 ++- test/CodeGen/X86/haddsub-broadcast.ll | 20 ++++++++++++++++++++ 3 files changed, 26 insertions(+), 5 deletions(-) create mode 100644 test/CodeGen/X86/haddsub-broadcast.ll diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 59670d0ec3c..fabacaefb6f 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -34326,14 +34326,14 @@ static SDValue foldShuffleOfHorizOp(SDNode *N, SelectionDAG &DAG) { // When the operands of a horizontal math op are identical, the low half of // the result is the same as the high half. If a target shuffle is also - // replicating low and high halves, we don't need the shuffle. + // replicating low and high halves (and without changing the type/length of + // the vector), we don't need the shuffle. if (Opcode == X86ISD::MOVDDUP || Opcode == X86ISD::VBROADCAST) { - if (HOp.getScalarValueSizeInBits() == 64) { + if (HOp.getScalarValueSizeInBits() == 64 && HOp.getValueType() == VT) { // movddup (hadd X, X) --> hadd X, X // broadcast (extract_vec_elt (hadd X, X), 0) --> hadd X, X assert((HOp.getValueType() == MVT::v2f64 || - HOp.getValueType() == MVT::v4f64) && HOp.getValueType() == VT && - "Unexpected type for h-op"); + HOp.getValueType() == MVT::v4f64) && "Unexpected type for h-op"); return updateHOp(HOp, DAG); } return SDValue(); diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h index 2cd49e47782..90188e758e5 100644 --- a/lib/Target/X86/X86ISelLowering.h +++ b/lib/Target/X86/X86ISelLowering.h @@ -425,7 +425,8 @@ namespace llvm { // Tests Types Of a FP Values for scalar types. VFPCLASSS, - // Broadcast scalar to vector. + // Broadcast (splat) scalar or element 0 of a vector. If the operand is + // a vector, this node may change the vector length as part of the splat. VBROADCAST, // Broadcast mask to vector. VBROADCASTM, diff --git a/test/CodeGen/X86/haddsub-broadcast.ll b/test/CodeGen/X86/haddsub-broadcast.ll new file mode 100644 index 00000000000..a37cf80ff79 --- /dev/null +++ b/test/CodeGen/X86/haddsub-broadcast.ll @@ -0,0 +1,20 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc < %s -mtriple=i686-- -mattr=avx2 | FileCheck %s + +; The broadcast node takes a vector operand as input and changes its length. + +define <4 x double> @PR43402(i64 %x) { +; CHECK-LABEL: PR43402: +; CHECK: # %bb.0: +; CHECK-NEXT: vmovsd {{.*#+}} xmm0 = mem[0],zero +; CHECK-NEXT: vunpcklps {{.*#+}} xmm0 = xmm0[0],mem[0],xmm0[1],mem[1] +; CHECK-NEXT: vsubpd {{\.LCPI.*}}, %xmm0, %xmm0 +; CHECK-NEXT: vhaddpd %xmm0, %xmm0, %xmm0 +; CHECK-NEXT: vbroadcastsd %xmm0, %ymm0 +; CHECK-NEXT: retl + %conv = uitofp i64 %x to double + %t2 = insertelement <4 x double> undef, double %conv, i32 0 + %t3 = shufflevector <4 x double> %t2, <4 x double> undef, <4 x i32> zeroinitializer + ret <4 x double> %t3 +} + -- 2.11.4.GIT