Add support for vector remainder operations.

llvm-svn: 43744
This commit is contained in:
Dan Gohman 2007-11-05 23:35:22 +00:00
parent 4decbc5002
commit 08143e397d
4 changed files with 36 additions and 15 deletions

View File

@ -2093,7 +2093,8 @@ unsigned division of its two arguments.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>urem</tt>' instruction must be
<a href="#t_integer">integer</a> values. Both arguments must have identical
types.</p>
types. This instruction can also take <a href="#t_vector">vector</a> versions
of the values in which case the elements must be integers.</p>
<h5>Semantics:</h5>
<p>This instruction returns the unsigned integer <i>remainder</i> of a division.
This instruction always performs an unsigned division to get the remainder,
@ -2112,7 +2113,10 @@ Instruction</a> </div>
</pre>
<h5>Overview:</h5>
<p>The '<tt>srem</tt>' instruction returns the remainder from the
signed division of its two operands.</p>
signed division of its two operands. This instruction can also take
<a href="#t_vector">vector</a> versions of the values in which case
the elements must be integers.</p>
</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>srem</tt>' instruction must be
<a href="#t_integer">integer</a> values. Both arguments must have identical
@ -2144,7 +2148,8 @@ division of its two operands.</p>
<h5>Arguments:</h5>
<p>The two arguments to the '<tt>frem</tt>' instruction must be
<a href="#t_floating">floating point</a> values. Both arguments must have
identical types.</p>
identical types. This instruction can also take <a href="#t_vector">vector</a>
versions of floating point values.</p>
<h5>Semantics:</h5>
<p>This instruction returns the <i>remainder</i> of a division.</p>
<h5>Example:</h5>

View File

@ -2812,11 +2812,6 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
!isa<VectorType>((*$2).get()))
GEN_ERROR(
"Arithmetic operator requires integer, FP, or packed operands");
if (isa<VectorType>((*$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);

View File

@ -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;
}

View File

@ -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
}