summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Target/X86/X86ISelDAGToDAG.cpp14
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp21
-rw-r--r--llvm/test/CodeGen/X86/divrem8_ext.ll4
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
OpenPOWER on IntegriCloud