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