diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0ec42d7306d43..90f437ec1b2f8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -12359,6 +12359,16 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, N0.getOperand(0)); + // fold (sext (sext_inreg x)) -> (sext (trunc x)) + if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG) { + SDValue N00 = N0.getOperand(0); + EVT ExtVT = cast(N0->getOperand(1))->getVT(); + if (N00.getOpcode() == ISD::TRUNCATE && (!LegalOperations || TLI.isTypeLegal(ExtVT))) { + SDValue T = DAG.getNode(ISD::TRUNCATE, DL, ExtVT, N00.getOperand(0)); + return DAG.getNode(ISD::SIGN_EXTEND, DL, VT, T); + } + } + if (N0.getOpcode() == ISD::TRUNCATE) { // fold (sext (truncate (load x))) -> (sext (smaller load x)) // fold (sext (truncate (srl (load x), c))) -> (sext (smaller load (x+c/n))) diff --git a/llvm/test/CodeGen/X86/sdiv_fix.ll b/llvm/test/CodeGen/X86/sdiv_fix.ll index d0a1ed34359d7..e747692412034 100644 --- a/llvm/test/CodeGen/X86/sdiv_fix.ll +++ b/llvm/test/CodeGen/X86/sdiv_fix.ll @@ -65,10 +65,8 @@ define i16 @func(i16 %x, i16 %y) nounwind { define i16 @func2(i8 %x, i8 %y) nounwind { ; X64-LABEL: func2: ; X64: # %bb.0: -; X64-NEXT: movsbl %dil, %eax -; X64-NEXT: movsbl %sil, %ecx -; X64-NEXT: movswl %cx, %esi -; X64-NEXT: movswl %ax, %ecx +; X64-NEXT: movsbl %sil, %esi +; X64-NEXT: movsbl %dil, %ecx ; X64-NEXT: shll $14, %ecx ; X64-NEXT: movl %ecx, %eax ; X64-NEXT: cltd diff --git a/llvm/test/CodeGen/X86/sdiv_fix_sat.ll b/llvm/test/CodeGen/X86/sdiv_fix_sat.ll index 6bec36638720d..b7387651f8c44 100644 --- a/llvm/test/CodeGen/X86/sdiv_fix_sat.ll +++ b/llvm/test/CodeGen/X86/sdiv_fix_sat.ll @@ -81,10 +81,8 @@ define i16 @func2(i8 %x, i8 %y) nounwind { ; ; X64-LABEL: func2: ; X64: # %bb.0: -; X64-NEXT: movsbl %dil, %eax -; X64-NEXT: movsbl %sil, %ecx -; X64-NEXT: movswl %cx, %esi -; X64-NEXT: movswl %ax, %ecx +; X64-NEXT: movsbl %sil, %esi +; X64-NEXT: movsbl %dil, %ecx ; X64-NEXT: shll $14, %ecx ; X64-NEXT: movl %ecx, %eax ; X64-NEXT: cltd