OSDN Git Service

Subzero: Enable Non-SFI vector cross tests.
authorJim Stichnoth <stichnot@chromium.org>
Wed, 6 Jan 2016 17:34:36 +0000 (09:34 -0800)
committerJim Stichnoth <stichnot@chromium.org>
Wed, 6 Jan 2016 17:34:36 +0000 (09:34 -0800)
The driver programs for vector tests use a loop to initialize vector-type values one element at a time.  The PNaCl ABI requires the vector element index to be a constant, and the createConstantInsertExtractElementIndexPass() transformation creates an alloca instruction.  When this alloca is inside a loop, it can (and does in the cross tests) cause a stack overflow.

The workaround here is to use a noinline helper function to do the insertelement.

We didn't run into this problem until now because native and sandbox cross tests build the driver in a different way that presumably avoids running the PNaCl ABI simplification passes.

BUG= none
R=jpp@chromium.org

Review URL: https://codereview.chromium.org/1560933002 .

Makefile.standalone
crosstest/insertelement.h [new file with mode: 0644]
crosstest/test_arith_main.cpp
crosstest/test_icmp_main.cpp
crosstest/test_select_main.cpp
pydir/crosstest.py

index d84e928..64f47f6 100644 (file)
@@ -405,7 +405,7 @@ check-xtest: $(OBJDIR)/pnacl-sz make_symlink runtime
           -i x8632,native,sse2 \
           -i x8632,native,sse4.1,test_vector_ops \
           -i x8632,sandbox,sse4.1,Om1 \
-          -i x8632,nonsfi,sse2,O2 -e x8632,nonsfi,test_select \
+          -i x8632,nonsfi,sse2,O2 \
           -i x8664,native,sse2 \
           -i x8664,native,sse4.1,test_vector_ops \
           -e x8664,sandbox,sse4.1,Om1 \
diff --git a/crosstest/insertelement.h b/crosstest/insertelement.h
new file mode 100644 (file)
index 0000000..701a0f8
--- /dev/null
@@ -0,0 +1,27 @@
+//===- subzero/crosstest/insertelement.h - Helper for PNaCl workaround. ---===//
+//
+//                        The Subzero Code Generator
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Helper function to work around a potential stack overflow issue.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef INSERTELEMENT_H
+#define INSERTELEMENT_H
+
+// Helper function to perform the insertelement bitcode instruction.  The PNaCl
+// ABI simplifications transform insertelement/extractelement instructions with
+// a non-constant index into something involving alloca.  This can cause a stack
+// overflow if the alloca is inside a loop.
+template <typename VectorType, typename ElementType>
+void __attribute__((noinline))
+setElement(VectorType &Value, size_t Index, ElementType Element) {
+  Value[Index] = Element;
+}
+
+#endif // INSERTELEMENT_H
index db03709..9cee652 100644 (file)
 // Subzero_ namespace, corresponding to the llc and Subzero translated
 // object files, respectively.
 #include "test_arith.h"
-#include "xdefs.h"
 
 namespace Subzero_ {
 #include "test_arith.h"
 }
 
+#include "insertelement.h"
+#include "xdefs.h"
+
 template <class T> bool inputsMayTriggerException(T Value1, T Value2) {
   // Avoid HW divide-by-zero exception.
   if (Value2 == 0)
@@ -162,7 +164,7 @@ const static size_t MaxTestsPerFunc = 100000;
 
 template <typename TypeUnsignedLabel, typename TypeSignedLabel>
 void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
-#if !defined(ARM32) && !defined(NONSFI)
+#if !defined(ARM32)
   // TODO(jpp): remove this once vector support is implemented.
   typedef typename Vectors<TypeUnsignedLabel>::Ty TypeUnsigned;
   typedef typename Vectors<TypeSignedLabel>::Ty TypeSigned;
@@ -212,8 +214,8 @@ void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
           continue;
         if (Funcs[f].MaskShiftOperations)
           Element2 &= CHAR_BIT * sizeof(ElementTypeUnsigned) - 1;
-        Value1[j] = Element1;
-        Value2[j] = Element2;
+        setElement(Value1, j, Element1);
+        setElement(Value2, j, Element2);
       }
       // Perform the test.
       TypeUnsigned ResultSz, ResultLlc;
@@ -239,7 +241,7 @@ void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
       }
     }
   }
-#endif // !ARM32 && !NONSFI
+#endif // !ARM32
 }
 
 template <typename Type>
@@ -315,7 +317,7 @@ void testsFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
 }
 
 void testsVecFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
-#if !defined(ARM32) && !defined(NONSFI)
+#if !defined(ARM32)
   // TODO(jpp): remove this once vector support is implemented.
   static const float NegInf = -1.0 / 0.0;
   static const float PosInf = 1.0 / 0.0;
@@ -343,8 +345,8 @@ void testsVecFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
       // Initialize the test vectors.
       v4f32 Value1, Value2;
       for (size_t j = 0; j < NumElementsInType; ++j) {
-        Value1[j] = Values[Index() % NumValues];
-        Value2[j] = Values[Index() % NumValues];
+        setElement(Value1, j, Values[Index() % NumValues]);
+        setElement(Value2, j, Values[Index() % NumValues]);
       }
       // Perform the test.
       v4f32 ResultSz = Funcs[f].FuncSz(Value1, Value2);
@@ -375,7 +377,7 @@ void testsVecFp(size_t &TotalTests, size_t &Passes, size_t &Failures) {
       }
     }
   }
-#endif // !ARM32 && !NONSFI
+#endif // !ARM32
 }
 
 #ifdef X8664_STACK_HACK
index 4378a6d..d34c57e 100644 (file)
@@ -28,6 +28,7 @@ namespace Subzero_ {
 #include "test_icmp.h"
 }
 
+#include "insertelement.h"
 #include "xdefs.h"
 
 volatile unsigned Values[] = {
@@ -197,10 +198,12 @@ const static size_t MaxTestsPerFunc = 100000;
 
 template <typename TypeUnsignedLabel, typename TypeSignedLabel>
 void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
-#if !defined(ARM32) && !defined(NONSFI)
+#if !defined(ARM32)
   // TODO(jpp): remove this once vector support is implemented.
   typedef typename Vectors<TypeUnsignedLabel>::Ty TypeUnsigned;
   typedef typename Vectors<TypeSignedLabel>::Ty TypeSigned;
+  typedef typename Vectors<TypeUnsignedLabel>::ElementTy ElementTypeUnsigned;
+  typedef typename Vectors<TypeSignedLabel>::ElementTy ElementTypeSigned;
   typedef TypeUnsigned (*FuncTypeUnsigned)(TypeUnsigned, TypeUnsigned);
   typedef TypeSigned (*FuncTypeSigned)(TypeSigned, TypeSigned);
   static struct {
@@ -232,10 +235,9 @@ void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
     for (size_t i = 0; i < MaxTestsPerFunc; ++i) {
       // Initialize the test vectors.
       TypeUnsigned Value1, Value2;
-      for (size_t j = 0; j < NumElementsInType;) {
-        Value1[j] = Values[Index() % NumValues];
-        Value2[j] = Values[Index() % NumValues];
-        ++j;
+      for (size_t j = 0; j < NumElementsInType; ++j) {
+        setElement(Value1, j, Values[Index() % NumValues]);
+        setElement(Value2, j, Values[Index() % NumValues]);
       }
       // Perform the test.
       TypeUnsigned ResultSz = Funcs[f].FuncSz(Value1, Value2);
@@ -255,11 +257,13 @@ void testsVecInt(size_t &TotalTests, size_t &Passes, size_t &Failures) {
       }
     }
   }
-#endif // !ARM32 && !NONSFI
+#endif // !ARM32
 }
 
 // Return true on wraparound
-template <typename T> bool incrementI1Vector(typename Vectors<T>::Ty &Vect) {
+template <typename T>
+bool __attribute__((noinline))
+incrementI1Vector(typename Vectors<T>::Ty &Vect) {
   size_t Pos = 0;
   const static size_t NumElements = Vectors<T>::NumElements;
   for (Pos = 0; Pos < NumElements; ++Pos) {
@@ -274,7 +278,7 @@ template <typename T> bool incrementI1Vector(typename Vectors<T>::Ty &Vect) {
 
 template <typename T>
 void testsVecI1(size_t &TotalTests, size_t &Passes, size_t &Failures) {
-#if !defined(ARM32) && !defined(NONSFI)
+#if !defined(ARM32)
   // TODO(jpp): remove this once vector support is implemented.
   typedef typename Vectors<T>::Ty Ty;
   typedef Ty (*FuncType)(Ty, Ty);
@@ -324,8 +328,8 @@ void testsVecI1(size_t &TotalTests, size_t &Passes, size_t &Failures) {
         Ty Value1, Value2;
         // Initialize the test vectors.
         for (size_t j = 0; j < NumElements; ++j) {
-          Value1[j] = Index() % 2;
-          Value2[j] = Index() % 2;
+          setElement(Value1, j, Index() % 2);
+          setElement(Value2, j, Index() % 2);
         }
         // Perform the test.
         Ty ResultSz = Funcs[f].FuncSz(Value1, Value2);
@@ -343,7 +347,7 @@ void testsVecI1(size_t &TotalTests, size_t &Passes, size_t &Failures) {
       }
     }
   }
-#endif // !ARM32 && !NONSFI
+#endif // !ARM32
 }
 
 #ifdef X8664_STACK_HACK
index 1973416..d3408a0 100644 (file)
@@ -25,6 +25,8 @@ namespace Subzero_ {
 #include "test_select.h"
 }
 
+#include "insertelement.h"
+
 static const size_t MaxTestsPerFunc = 100000;
 
 template <typename T, typename TI1>
@@ -43,9 +45,9 @@ void testSelect(size_t &TotalTests, size_t &Passes, size_t &Failures) {
     TyI1 Cond;
     Ty Value1, Value2;
     for (size_t j = 0; j < NumElements; ++j) {
-      Cond[j] = Index() % 2;
-      Value1[j] = Values[Index() % NumValues];
-      Value2[j] = Values[Index() % NumValues];
+      setElement(Cond, j, Index() % 2);
+      setElement(Value1, j, Values[Index() % NumValues]);
+      setElement(Value2, j, Values[Index() % NumValues]);
     }
     Ty ResultLlc = select(Cond, Value1, Value2);
     Ty ResultSz = Subzero_::select(Cond, Value1, Value2);
@@ -79,9 +81,9 @@ void testSelect<v4f32, v4i1>(size_t &TotalTests, size_t &Passes,
     v4si32 Cond;
     v4f32 Value1, Value2;
     for (size_t j = 0; j < NumElements; ++j) {
-      Cond[j] = Index() % 2;
-      Value1[j] = Values[Index() % NumValues];
-      Value2[j] = Values[Index() % NumValues];
+      setElement(Cond, j, Index() % 2);
+      setElement(Value1, j, Values[Index() % NumValues]);
+      setElement(Value2, j, Values[Index() % NumValues]);
     }
     v4f32 ResultLlc = select(Cond, Value1, Value2);
     v4f32 ResultSz = Subzero_::select(Cond, Value1, Value2);
@@ -109,9 +111,9 @@ void testSelectI1(size_t &TotalTests, size_t &Passes, size_t &Failures) {
     Ty Cond;
     Ty Value1, Value2;
     for (size_t j = 0; j < NumElements; ++j) {
-      Cond[j] = Index() % 2;
-      Value1[j] = Index() % 2;
-      Value2[j] = Index() % 2;
+      setElement(Cond, j, Index() % 2);
+      setElement(Value1, j, Index() % 2);
+      setElement(Value2, j, Index() % 2);
     }
     Ty ResultLlc = select_i1(Cond, Value1, Value2);
     Ty ResultSz = Subzero_::select_i1(Cond, Value1, Value2);
index 50946ca..dc2da2b 100755 (executable)
@@ -126,7 +126,6 @@ def main():
             bitcode = os.path.join(args.dir, base + '.' + key + '.pnacl.ll')
             shellcmd(['{bin}/pnacl-clang'.format(bin=bindir),
                       ('-O2' if args.clang_opt else '-O0'),
-                      get_sfi_string(args, '', '-DNONSFI', ''),
                       ('-DARM32' if args.target == 'arm32' else ''), '-c', arg,
                       '-o', bitcode_nonfinal])
             shellcmd(['{bin}/pnacl-opt'.format(bin=bindir),
@@ -211,8 +210,6 @@ def main():
     if args.target == 'arm32':
       target_params.append('-DARM32')
       target_params.append('-static')
-    if args.nonsfi:
-      target_params.append('-DNONSFI')
 
     pure_c = os.path.splitext(args.driver)[1] == '.c'
     if not args.nonsfi:
@@ -242,7 +239,6 @@ def main():
         cc='clang' if pure_c else 'clang++')
     shellcmd([compiler,
               args.driver,
-              '-DNONSFI' if args.nonsfi else '',
               '-O2',
               '-o', bitcode_nonfinal,
               '-Wl,-r'