Add support for vector remainder operations.
authorDan Gohman <gohman@apple.com>
Mon, 5 Nov 2007 23:35:22 +0000 (23:35 +0000)
committerDan Gohman <gohman@apple.com>
Mon, 5 Nov 2007 23:35:22 +0000 (23:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43744 91177308-0d34-0410-b5e6-96231b3b80d8

docs/LangRef.html
lib/AsmParser/llvmAsmParser.y
lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
test/CodeGen/X86/vector-rem.ll [new file with mode: 0644]

index f6895a09ee7e179b2f70456f13b2f78c631cf393..46ec87eed267820ae843632f02452cb26b38b1c3 100644 (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>
index 708453858408cb2253afce1b9d6cbdffc8a8be3e..f1c385f70e7bd1a14e990afed4d6d03a48a02be8 100644 (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);
index 8b60d7c2ce11a52ea51b5174c583a9966997c496..d688465234b44b6c25d1e647efd9708d5fbca3d8 100644 (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;
     }
diff --git a/test/CodeGen/X86/vector-rem.ll b/test/CodeGen/X86/vector-rem.ll
new file mode 100644 (file)
index 0000000..cfdd34e
--- /dev/null
@@ -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
+}