<div dir="ltr">Thanks for fixing!</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Wed, Jul 2, 2014 at 8:18 AM, Benjamin Kramer <span dir="ltr"><<a href="mailto:benny.kra@gmail.com" target="_blank">benny.kra@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Wed, Jul 2, 2014 at 2:56 PM, Patrik Hägglund H<br>
<<a href="mailto:patrik.h.hagglund@ericsson.com">patrik.h.hagglund@ericsson.com</a>> wrote:<br>
> Hi Chandler,<br>
><br>
> This commit is causing a regression found by llvm-stress:<br>
><br>
> bin/llvm-stress -size 300 -seed 17093 | bin/llc -march=x86-64 -mcpu=corei7 -o /dev/null<br>
> llc: ../lib/CodeGen/SelectionDAG/SelectionDAG.cpp:5730: void llvm::SelectionDAG::ReplaceAllUsesWith(llvm::SDValue, llvm::SDValue): Assertion `From != To.getNode() && "Cannot replace uses of with self"' failed.<br>

> 0  llc             0x0000000001129a75 llvm::sys::PrintStackTrace(_IO_FILE*) + 37<br>
> 1  llc             0x0000000001129eb3<br>
> 2  libpthread.so.0 0x00007f211fcae7c0<br>
> 3  libc.so.6       0x00007f211efb2b35 gsignal + 53<br>
> 4  libc.so.6       0x00007f211efb4111 abort + 385<br>
> 5  libc.so.6       0x00007f211efab9f0 __assert_fail + 240<br>
> 6  llc             0x0000000000fc73af<br>
> 7  llc             0x0000000000fc7444 llvm::SelectionDAG::ReplaceAllUsesWith(llvm::SDNode*, llvm::SDValue const*) + 52<br>
> 8  llc             0x0000000000f27ff9<br>
> 9  llc             0x0000000000f28203 llvm::TargetLowering::DAGCombinerInfo::CombineTo(llvm::SDNode*, llvm::SDValue, bool) + 35<br>
> 10 llc             0x0000000000af4308 llvm::X86TargetLowering::PerformDAGCombine(llvm::SDNode*, llvm::TargetLowering::DAGCombinerInfo&) const + 65080<br>
> 11 llc             0x0000000000f28f7e<br>
> 12 llc             0x0000000000f288bb llvm::SelectionDAG::Combine(llvm::CombineLevel, llvm::AliasAnalysis&, llvm::CodeGenOpt::Level) + 939<br>
> 13 llc             0x000000000101819b llvm::SelectionDAGISel::CodeGenAndEmitDAG() + 3259<br>
> 14 llc             0x0000000001016aa8 llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) + 7096<br>
> 15 llc             0x0000000001014154 llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) + 1332<br>
> 16 llc             0x0000000000a6ce26<br>
> 17 llc             0x0000000000c6348c llvm::MachineFunctionPass::runOnFunction(llvm::Function&) + 124<br>
> 18 llc             0x0000000000e559ca llvm::FPPassManager::runOnFunction(llvm::Function&) + 362<br>
> 19 llc             0x0000000000e55c5b llvm::FPPassManager::runOnModule(llvm::Module&) + 43<br>
> 20 llc             0x0000000000e561f7 llvm::legacy::PassManagerImpl::run(llvm::Module&) + 999<br>
> 21 llc             0x000000000056d071 main + 6817<br>
> 22 libc.so.6       0x00007f211ef9ec16 __libc_start_main + 230<br>
> 23 llc             0x000000000056b4e9<br>
> Stack dump:<br>
> 0.      Program arguments: bin/llc -march=x86-64 -mcpu=corei7 -o /dev/null<br>
> 1.      Running pass 'Function Pass Manager' on module '<stdin>'.<br>
> 2.      Running pass 'X86 DAG->DAG Instruction Selection' on function '@autogen_SD17093'<br>
> Abort<br>
<br>
</div></div>Fixed in r212181.<br>
<br>
- Ben<br>
<div class="HOEnZb"><div class="h5">><br>
> /Patrik Hägglund<br>
> -----Original Message-----<br>
> From: <a href="mailto:llvm-commits-bounces@cs.uiuc.edu">llvm-commits-bounces@cs.uiuc.edu</a> [mailto:<a href="mailto:llvm-commits-bounces@cs.uiuc.edu">llvm-commits-bounces@cs.uiuc.edu</a>] On Behalf Of Chandler Carruth<br>

> Sent: den 27 juni 2014 13:40<br>
> To: <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> Subject: [llvm] r211892 - [x86] Teach the target combine step to aggressively fold pshufd insturcions.<br>
><br>
> Author: chandlerc<br>
> Date: Fri Jun 27 06:40:13 2014<br>
> New Revision: 211892<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=211892&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=211892&view=rev</a><br>
> Log:<br>
> [x86] Teach the target combine step to aggressively fold pshufd insturcions.<br>
><br>
> Summary:<br>
> This allows it to fold pshufd instructions across intervening<br>
> half-shuffles and other noise. This pattern actually shows up in the<br>
> generic lowering tests, but I've also added direct tests using<br>
> intrinsics to make sure that the specific desired functionality is<br>
> working even if the lowering stuff changes in the future.<br>
><br>
> Differential Revision: <a href="http://reviews.llvm.org/D4292" target="_blank">http://reviews.llvm.org/D4292</a><br>
><br>
> Modified:<br>
>     llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
>     llvm/trunk/test/CodeGen/X86/vector-shuffle-128-v8.ll<br>
>     llvm/trunk/test/CodeGen/X86/vector-shuffle-combining.ll<br>
><br>
> Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=211892&r1=211891&r2=211892&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=211892&r1=211891&r2=211892&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)<br>
> +++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Jun 27 06:40:13 2014<br>
> @@ -19061,6 +19061,79 @@ static SmallVector<int, 4> getPSHUFShuff<br>
>    }<br>
>  }<br>
><br>
> +/// \brief Search for a combinable shuffle across a chain ending in pshufd.<br>
> +///<br>
> +/// We walk up the chain and look for a combinable shuffle, skipping over<br>
> +/// shuffles that we could hoist this shuffle's transformation past without<br>
> +/// altering anything.<br>
> +static bool combineRedundantDWordShuffle(SDValue N, MutableArrayRef<int> Mask,<br>
> +                                         SelectionDAG &DAG,<br>
> +                                         TargetLowering::DAGCombinerInfo &DCI) {<br>
> +  assert(N.getOpcode() == X86ISD::PSHUFD &&<br>
> +         "Called with something other than an x86 128-bit half shuffle!");<br>
> +  SDLoc DL(N);<br>
> +<br>
> +  // Walk up a single-use chain looking for a combinable shuffle.<br>
> +  SDValue V = N.getOperand(0);<br>
> +  for (; V.hasOneUse(); V = V.getOperand(0)) {<br>
> +    switch (V.getOpcode()) {<br>
> +    default:<br>
> +      return false; // Nothing combined!<br>
> +<br>
> +    case ISD::BITCAST:<br>
> +      // Skip bitcasts as we always know the type for the target specific<br>
> +      // instructions.<br>
> +      continue;<br>
> +<br>
> +    case X86ISD::PSHUFD:<br>
> +      // Found another dword shuffle.<br>
> +      break;<br>
> +<br>
> +    case X86ISD::PSHUFLW:<br>
> +      // Check that the low words (being shuffled) are the identity in the<br>
> +      // dword shuffle, and the high words are self-contained.<br>
> +      if (Mask[0] != 0 || Mask[1] != 1 ||<br>
> +          !(Mask[2] >= 2 && Mask[2] < 4 && Mask[3] >= 2 && Mask[3] < 4))<br>
> +        return false;<br>
> +<br>
> +      continue;<br>
> +<br>
> +    case X86ISD::PSHUFHW:<br>
> +      // Check that the high words (being shuffled) are the identity in the<br>
> +      // dword shuffle, and the low words are self-contained.<br>
> +      if (Mask[2] != 2 || Mask[3] != 3 ||<br>
> +          !(Mask[0] >= 0 && Mask[0] < 2 && Mask[1] >= 0 && Mask[1] < 2))<br>
> +        return false;<br>
> +<br>
> +      continue;<br>
> +    }<br>
> +    // Break out of the loop if we break out of the switch.<br>
> +    break;<br>
> +  }<br>
> +<br>
> +  if (!V.hasOneUse())<br>
> +    // We fell out of the loop without finding a viable combining instruction.<br>
> +    return false;<br>
> +<br>
> +  // Record the old value to use in RAUW-ing.<br>
> +  SDValue Old = V;<br>
> +<br>
> +  // Merge this node's mask and our incoming mask.<br>
> +  SmallVector<int, 4> VMask = getPSHUFShuffleMask(V);<br>
> +  for (int &M : Mask)<br>
> +    M = VMask[M];<br>
> +  V = DAG.getNode(X86ISD::PSHUFD, DL, MVT::v4i32, V.getOperand(0),<br>
> +                  getV4X86ShuffleImm8ForMask(Mask, DAG));<br>
> +<br>
> +  // Replace N with its operand as we're going to combine that shuffle away.<br>
> +  DAG.ReplaceAllUsesWith(N, N.getOperand(0));<br>
> +<br>
> +  // Replace the combinable shuffle with the combined one, updating all users<br>
> +  // so that we re-evaluate the chain here.<br>
> +  DCI.CombineTo(Old.getNode(), V, /*AddTo*/ true);<br>
> +  return true;<br>
> +}<br>
> +<br>
>  /// \brief Search for a combinable shuffle across a chain ending in pshuflw or pshufhw.<br>
>  ///<br>
>  /// We walk up the chain, skipping shuffles of the other half and looking<br>
> @@ -19194,18 +19267,11 @@ static SDValue PerformTargetShuffleCombi<br>
>        return DAG.getNode(ISD::BITCAST, DL, MVT::v8i16, V);<br>
>      }<br>
><br>
> -    // Fallthrough<br>
> +    break;<br>
> +<br>
>    case X86ISD::PSHUFD:<br>
> -    if (V.getOpcode() == N.getOpcode()) {<br>
> -      // If we have two sequential shuffles of the same kind we can always fold<br>
> -      // them. Even if there are multiple uses, this is beneficial because it<br>
> -      // breaks a dependency.<br>
> -      SmallVector<int, 4> VMask = getPSHUFShuffleMask(V);<br>
> -      for (int &M : Mask)<br>
> -        M = VMask[M];<br>
> -      return DAG.getNode(N.getOpcode(), DL, VT, V.getOperand(0),<br>
> -                         getV4X86ShuffleImm8ForMask(Mask, DAG));<br>
> -    }<br>
> +    if (combineRedundantDWordShuffle(N, Mask, DAG, DCI))<br>
> +      return SDValue(); // We combined away this shuffle.<br>
><br>
>      break;<br>
>    }<br>
><br>
> Modified: llvm/trunk/test/CodeGen/X86/vector-shuffle-128-v8.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-shuffle-128-v8.ll?rev=211892&r1=211891&r2=211892&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-shuffle-128-v8.ll?rev=211892&r1=211891&r2=211892&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/X86/vector-shuffle-128-v8.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/X86/vector-shuffle-128-v8.ll Fri Jun 27 06:40:13 2014<br>
> @@ -157,9 +157,8 @@ define <8 x i16> @shuffle_v8i16_26401375<br>
>  ; CHECK-SSE2:       # BB#0:<br>
>  ; CHECK-SSE2-NEXT:    pshuflw {{.*}} # xmm0 = xmm0[0,2,1,3,4,5,6,7]<br>
>  ; CHECK-SSE2-NEXT:    pshufhw {{.*}} # xmm0 = xmm0[0,1,2,3,7,5,4,6]<br>
> -; CHECK-SSE2-NEXT:    pshufd {{.*}} # xmm0 = xmm0[0,3,2,1]<br>
> +; CHECK-SSE2-NEXT:    pshufd {{.*}} # xmm0 = xmm0[0,3,1,2]<br>
>  ; CHECK-SSE2-NEXT:    pshuflw {{.*}} # xmm0 = xmm0[1,3,2,0,4,5,6,7]<br>
> -; CHECK-SSE2-NEXT:    pshufd {{.*}} # xmm0 = xmm0[0,1,3,2]<br>
>  ; CHECK-SSE2-NEXT:    retq<br>
>    %shuffle = shufflevector <8 x i16> %a, <8 x i16> %b, <8 x i32> <i32 2, i32 6, i32 4, i32 0, i32 1, i32 3, i32 7, i32 5><br>
>    ret <8 x i16> %shuffle<br>
><br>
> Modified: llvm/trunk/test/CodeGen/X86/vector-shuffle-combining.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-shuffle-combining.ll?rev=211892&r1=211891&r2=211892&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/vector-shuffle-combining.ll?rev=211892&r1=211891&r2=211892&view=diff</a><br>

> ==============================================================================<br>
> --- llvm/trunk/test/CodeGen/X86/vector-shuffle-combining.ll (original)<br>
> +++ llvm/trunk/test/CodeGen/X86/vector-shuffle-combining.ll Fri Jun 27 06:40:13 2014<br>
> @@ -3,9 +3,69 @@<br>
>  target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"<br>
>  target triple = "x86_64-unknown-unknown"<br>
><br>
> +declare <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32>, i8)<br>
>  declare <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16>, i8)<br>
>  declare <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16>, i8)<br>
><br>
> +define <4 x i32> @combine_pshufd1(<4 x i32> %a) {<br>
> +; CHECK-SSE2-LABEL: @combine_pshufd1<br>
> +; CHECK-SSE2:       # BB#0:<br>
> +; CHECK-SSE2-NEXT:    retq<br>
> +  %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27)<br>
> +  %c = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %b, i8 27)<br>
> +  ret <4 x i32> %c<br>
> +}<br>
> +<br>
> +define <4 x i32> @combine_pshufd2(<4 x i32> %a) {<br>
> +; CHECK-SSE2-LABEL: @combine_pshufd2<br>
> +; CHECK-SSE2:       # BB#0:<br>
> +; CHECK-SSE2-NEXT:    retq<br>
> +  %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27)<br>
> +  %b.cast = bitcast <4 x i32> %b to <8 x i16><br>
> +  %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b.cast, i8 -28)<br>
> +  %c.cast = bitcast <8 x i16> %c to <4 x i32><br>
> +  %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 27)<br>
> +  ret <4 x i32> %d<br>
> +}<br>
> +<br>
> +define <4 x i32> @combine_pshufd3(<4 x i32> %a) {<br>
> +; CHECK-SSE2-LABEL: @combine_pshufd3<br>
> +; CHECK-SSE2:       # BB#0:<br>
> +; CHECK-SSE2-NEXT:    retq<br>
> +  %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 27)<br>
> +  %b.cast = bitcast <4 x i32> %b to <8 x i16><br>
> +  %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b.cast, i8 -28)<br>
> +  %c.cast = bitcast <8 x i16> %c to <4 x i32><br>
> +  %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 27)<br>
> +  ret <4 x i32> %d<br>
> +}<br>
> +<br>
> +define <4 x i32> @combine_pshufd4(<4 x i32> %a) {<br>
> +; CHECK-SSE2-LABEL: @combine_pshufd4<br>
> +; CHECK-SSE2:       # BB#0:<br>
> +; CHECK-SSE2-NEXT:    pshufhw {{.*}} # xmm0 = xmm0[0,1,2,3,7,6,5,4]<br>
> +; CHECK-SSE2-NEXT:    retq<br>
> +  %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 -31)<br>
> +  %b.cast = bitcast <4 x i32> %b to <8 x i16><br>
> +  %c = call <8 x i16> @llvm.x86.sse2.pshufh.w(<8 x i16> %b.cast, i8 27)<br>
> +  %c.cast = bitcast <8 x i16> %c to <4 x i32><br>
> +  %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 -31)<br>
> +  ret <4 x i32> %d<br>
> +}<br>
> +<br>
> +define <4 x i32> @combine_pshufd5(<4 x i32> %a) {<br>
> +; CHECK-SSE2-LABEL: @combine_pshufd5<br>
> +; CHECK-SSE2:       # BB#0:<br>
> +; CHECK-SSE2-NEXT:    pshuflw {{.*}} # xmm0 = xmm0[3,2,1,0,4,5,6,7]<br>
> +; CHECK-SSE2-NEXT:    retq<br>
> +  %b = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %a, i8 -76)<br>
> +  %b.cast = bitcast <4 x i32> %b to <8 x i16><br>
> +  %c = call <8 x i16> @llvm.x86.sse2.pshufl.w(<8 x i16> %b.cast, i8 27)<br>
> +  %c.cast = bitcast <8 x i16> %c to <4 x i32><br>
> +  %d = call <4 x i32> @llvm.x86.sse2.pshuf.d(<4 x i32> %c.cast, i8 -76)<br>
> +  ret <4 x i32> %d<br>
> +}<br>
> +<br>
>  define <8 x i16> @combine_pshuflw1(<8 x i16> %a) {<br>
>  ; CHECK-SSE2-LABEL: @combine_pshuflw1<br>
>  ; CHECK-SSE2:       # BB#0:<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</div></div></blockquote></div><br></div>