diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 14 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 21 | ||||
| -rw-r--r-- | llvm/test/CodeGen/X86/divrem8_ext.ll | 4 |
3 files changed, 21 insertions, 18 deletions
diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 3aa3244a706..d1f901e5da1 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -2912,19 +2912,7 @@ void X86DAGToDAGISel::Select(SDNode *Node) { if (Opcode == X86ISD::UDIVREM8_ZEXT_HREG || Opcode == X86ISD::SDIVREM8_SEXT_HREG) { - if (Node->getValueType(1) == MVT::i64) { - // It's not possible to directly movsx AH to a 64bit register, because - // the latter needs the REX prefix, but the former can't have it. - assert(Opcode != X86ISD::SDIVREM8_SEXT_HREG && - "Unexpected i64 sext of h-register"); - Result = - SDValue(CurDAG->getMachineNode( - TargetOpcode::SUBREG_TO_REG, dl, MVT::i64, - CurDAG->getTargetConstant(0, dl, MVT::i64), Result, - CurDAG->getTargetConstant(X86::sub_32bit, dl, - MVT::i32)), - 0); - } + assert(Node->getValueType(1) == MVT::i32 && "Unexpected result type!"); } else { Result = CurDAG->getTargetExtractSubreg(X86::sub_8bit, dl, MVT::i8, Result); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 576986dc965..53bc6adf601 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -27267,6 +27267,13 @@ void X86TargetLowering::computeKnownBitsForTargetNode(const SDValue Op, Known.Zero &= Known2.Zero; break; } + case X86ISD::UDIVREM8_ZEXT_HREG: + // TODO: Support more than just the zero extended bits? + if (Op.getResNo() != 1) + break; + // The remainder is zero extended. + Known.Zero.setBitsFrom(8); + break; } } @@ -27346,6 +27353,12 @@ unsigned X86TargetLowering::ComputeNumSignBitsForTargetNode( unsigned Tmp1 = DAG.ComputeNumSignBits(Op.getOperand(1), Depth+1); return std::min(Tmp0, Tmp1); } + case X86ISD::SDIVREM8_SEXT_HREG: + // TODO: Support more than just the sign extended bits? + if (Op.getResNo() != 1) + break; + // The remainder is sign extended. + return VTBits - 7; } // Fallback case. @@ -34853,15 +34866,19 @@ static SDValue getDivRem8(SDNode *N, SelectionDAG &DAG) { EVT VT = N->getValueType(0); EVT InVT = N0.getValueType(); - if (N0.getResNo() != 1 || InVT != MVT::i8 || VT != MVT::i32) + if (N0.getResNo() != 1 || InVT != MVT::i8 || + !(VT == MVT::i32 || VT == MVT::i64)) return SDValue(); - SDVTList NodeTys = DAG.getVTList(MVT::i8, VT); + SDVTList NodeTys = DAG.getVTList(MVT::i8, MVT::i32); auto DivRemOpcode = OpcodeN0 == ISD::SDIVREM ? X86ISD::SDIVREM8_SEXT_HREG : X86ISD::UDIVREM8_ZEXT_HREG; SDValue R = DAG.getNode(DivRemOpcode, SDLoc(N), NodeTys, N0.getOperand(0), N0.getOperand(1)); DAG.ReplaceAllUsesOfValueWith(N0.getValue(0), R.getValue(0)); + // If this was a 64-bit extend, complete it. + if (VT == MVT::i64) + return DAG.getNode(OpcodeN, SDLoc(N), VT, R.getValue(1)); return R.getValue(1); } diff --git a/llvm/test/CodeGen/X86/divrem8_ext.ll b/llvm/test/CodeGen/X86/divrem8_ext.ll index 7521156a370..c49be4b2d04 100644 --- a/llvm/test/CodeGen/X86/divrem8_ext.ll +++ b/llvm/test/CodeGen/X86/divrem8_ext.ll @@ -92,7 +92,6 @@ define i64 @test_urem_zext64_ah(i8 %x, i8 %y) { ; X64-NEXT: # kill: %EAX<def> %EAX<kill> %AX<def> ; X64-NEXT: divb %sil ; X64-NEXT: movzbl %ah, %eax # NOREX -; X64-NEXT: movzbl %al, %eax ; X64-NEXT: retq %1 = urem i8 %x, %y %2 = zext i8 %1 to i64 @@ -190,7 +189,7 @@ define i64 @test_srem_sext64_ah(i8 %x, i8 %y) { ; X64-NEXT: cbtw ; X64-NEXT: idivb %sil ; X64-NEXT: movsbl %ah, %eax # NOREX -; X64-NEXT: movsbq %al, %rax +; X64-NEXT: cltq ; X64-NEXT: retq %1 = srem i8 %x, %y %2 = sext i8 %1 to i64 @@ -215,7 +214,6 @@ define i64 @pr25754(i8 %a, i8 %c) { ; X64-NEXT: # kill: %EAX<def> %EAX<kill> %AX<def> ; X64-NEXT: divb %sil ; X64-NEXT: movzbl %ah, %ecx # NOREX -; X64-NEXT: movzbl %cl, %ecx ; X64-NEXT: movzbl %al, %eax ; X64-NEXT: addq %rcx, %rax ; X64-NEXT: retq |

