Index: lib/CodeGen/SelectionDAG/DAGCombiner.cpp =================================================================== --- lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -6012,6 +6012,13 @@ Shift = Op; return true; } + if (Op.getOpcode() == ISD::ADD && Op.getOperand(0) == Op.getOperand(1)) { + SDLoc DL(Op); + EVT VT = Op.getValueType(); + Shift = DAG.getNode(ISD::SHL, DL, VT, Op.getOperand(0), + DAG.getShiftAmountConstant(1, VT, DL)); + return true; + } return false; } Index: test/CodeGen/X86/rotate-extract-vector.ll =================================================================== --- test/CodeGen/X86/rotate-extract-vector.ll +++ test/CodeGen/X86/rotate-extract-vector.ll @@ -285,9 +285,10 @@ define <4 x i32> @extract_add_1(<4 x i32> %i) nounwind { ; CHECK-LABEL: extract_add_1: ; CHECK: # %bb.0: -; CHECK-NEXT: vpaddd %xmm0, %xmm0, %xmm1 -; CHECK-NEXT: vpsrld $31, %xmm0, %xmm0 -; CHECK-NEXT: vpor %xmm0, %xmm1, %xmm0 +; CHECK-NEXT: # kill: def $xmm0 killed $xmm0 def $zmm0 +; CHECK-NEXT: vprold $1, %zmm0, %zmm0 +; CHECK-NEXT: # kill: def $xmm0 killed $xmm0 killed $zmm0 +; CHECK-NEXT: vzeroupper ; CHECK-NEXT: ret{{[l|q]}} %ii = add <4 x i32> %i, %i %rhs = lshr <4 x i32> %i, Index: test/CodeGen/X86/rotate-extract.ll =================================================================== --- test/CodeGen/X86/rotate-extract.ll +++ test/CodeGen/X86/rotate-extract.ll @@ -270,18 +270,14 @@ define i32 @extract_add_1(i32 %i) nounwind { ; X86-LABEL: extract_add_1: ; X86: # %bb.0: -; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx -; X86-NEXT: leal (%ecx,%ecx), %eax -; X86-NEXT: shrl $31, %ecx -; X86-NEXT: orl %ecx, %eax +; X86-NEXT: movl {{[0-9]+}}(%esp), %eax +; X86-NEXT: roll %eax ; X86-NEXT: retl ; ; X64-LABEL: extract_add_1: ; X64: # %bb.0: -; X64-NEXT: # kill: def $edi killed $edi def $rdi -; X64-NEXT: leal (%rdi,%rdi), %eax -; X64-NEXT: shrl $31, %edi -; X64-NEXT: orl %edi, %eax +; X64-NEXT: movl %edi, %eax +; X64-NEXT: roll %eax ; X64-NEXT: retq %ii = add i32 %i, %i %rhs = lshr i32 %i, 31