From: Dan Gohman
Date: Mon, 5 Nov 2007 23:35:22 +0000 (+0000)
Subject: Add support for vector remainder operations.
X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=80176319f3ea5d3d943aa540e76381e8567f5dcb;p=oota-llvm.git
Add support for vector remainder operations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43744 91177308-0d34-0410-b5e6-96231b3b80d8
---
diff --git a/docs/LangRef.html b/docs/LangRef.html
index f6895a09ee7..46ec87eed26 100644
--- a/docs/LangRef.html
+++ b/docs/LangRef.html
@@ -2093,7 +2093,8 @@ unsigned division of its two arguments.
Arguments:
The two arguments to the 'urem' instruction must be
integer values. Both arguments must have identical
-types.
+types. This instruction can also take vector versions
+of the values in which case the elements must be integers.
Semantics:
This instruction returns the unsigned integer remainder of a division.
This instruction always performs an unsigned division to get the remainder,
@@ -2112,7 +2113,10 @@ Instruction
Overview:
The 'srem' instruction returns the remainder from the
-signed division of its two operands.
+signed division of its two operands. This instruction can also take
+vector versions of the values in which case
+the elements must be integers.
+
Arguments:
The two arguments to the 'srem' instruction must be
integer values. Both arguments must have identical
@@ -2144,7 +2148,8 @@ division of its two operands.
Arguments:
The two arguments to the 'frem' instruction must be
floating point values. Both arguments must have
-identical types.
+identical types. This instruction can also take vector
+versions of floating point values.
Semantics:
This instruction returns the remainder of a division.
Example:
diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y
index 70845385840..f1c385f70e7 100644
--- a/lib/AsmParser/llvmAsmParser.y
+++ b/lib/AsmParser/llvmAsmParser.y
@@ -2812,11 +2812,6 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
!isa((*$2).get()))
GEN_ERROR(
"Arithmetic operator requires integer, FP, or packed operands");
- if (isa((*$2).get()) &&
- ($1 == Instruction::URem ||
- $1 == Instruction::SRem ||
- $1 == Instruction::FRem))
- GEN_ERROR("Remainder not supported on vector types");
Value* val1 = getVal(*$2, $3);
CHECK_FOR_ERROR
Value* val2 = getVal(*$2, $5);
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 8b60d7c2ce1..d688465234b 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -2925,6 +2925,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
Result = DAG.getNode(DivOpc, VT, Tmp1, Tmp2);
Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2);
Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result);
+ } else if (MVT::isVector(VT)) {
+ Result = LegalizeOp(UnrollVectorOp(Op));
} else {
assert(VT == MVT::i32 &&
"Cannot expand this binary operator!");
@@ -2933,13 +2935,17 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
SDOperand Dummy;
Result = ExpandLibCall(TLI.getLibcallName(LC), Node, isSigned, Dummy);
}
- } else {
- // Floating point mod -> fmod libcall.
- RTLIB::Libcall LC = VT == MVT::f32
- ? RTLIB::REM_F32 : RTLIB::REM_F64;
- SDOperand Dummy;
- Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
- false/*sign irrelevant*/, Dummy);
+ } else if (MVT::isFloatingPoint(VT)) {
+ if (MVT::isVector(VT)) {
+ Result = LegalizeOp(UnrollVectorOp(Op));
+ } else {
+ // Floating point mod -> fmod libcall.
+ RTLIB::Libcall LC = VT == MVT::f32
+ ? RTLIB::REM_F32 : RTLIB::REM_F64;
+ SDOperand Dummy;
+ Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
+ false/*sign irrelevant*/, Dummy);
+ }
}
break;
}
diff --git a/test/CodeGen/X86/vector-rem.ll b/test/CodeGen/X86/vector-rem.ll
new file mode 100644
index 00000000000..cfdd34ee1c9
--- /dev/null
+++ b/test/CodeGen/X86/vector-rem.ll
@@ -0,0 +1,15 @@
+; RUN: llvm-as < %s | llc -march=x86-64 | grep div | count 8
+; RUN: llvm-as < %s | llc -march=x86-64 | grep fmodf | count 4
+
+define <4 x i32> @foo(<4 x i32> %t, <4 x i32> %u) {
+ %m = srem <4 x i32> %t, %u
+ ret <4 x i32> %m
+}
+define <4 x i32> @bar(<4 x i32> %t, <4 x i32> %u) {
+ %m = urem <4 x i32> %t, %u
+ ret <4 x i32> %m
+}
+define <4 x float> @qux(<4 x float> %t, <4 x float> %u) {
+ %m = frem <4 x float> %t, %u
+ ret <4 x float> %m
+}