CellSPU:
- Fix (brcond (setq ...)) bug, where BRNZ should have been used vice BRZ.
- Kill unused/unnecessary nodes in SPUNodes.td
- Beef out the i64operations.c test harness to use a lot of unaligned
  loads, test loops and LLVM loop/basic block optimizations; run the
  test harness successfully on real Cell hardware.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61664 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGen/CellSPU/icmp64.ll b/test/CodeGen/CellSPU/icmp64.ll
index d2b4fc0..0b5eaaf 100644
--- a/test/CodeGen/CellSPU/icmp64.ll
+++ b/test/CodeGen/CellSPU/icmp64.ll
@@ -1,10 +1,11 @@
 ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s
-; RUN: grep ceq                                %t1.s | count 4
+; RUN: grep ceq                                %t1.s | count 6
 ; RUN: grep cgti                               %t1.s | count 4
+; RUN: grep clgt                               %t1.s | count 2
 ; RUN: grep gb                                 %t1.s | count 4
-; RUN: grep fsm                                %t1.s | count 2
+; RUN: grep fsm                                %t1.s | count 3
 ; RUN: grep xori                               %t1.s | count 1
-; RUN: grep selb                               %t1.s | count 2
+; RUN: grep selb                               %t1.s | count 5
 
 target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128"
 target triple = "spu"
@@ -39,19 +40,19 @@
        ret i1 %A
 }
 
-;; define i64 @icmp_ugt_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
-;; entry:
-;;        %A = icmp ugt i64 %arg1, %arg2
-;;        %B = select i1 %A, i64 %val1, i64 %val2
-;;        ret i64 %B
-;; }
-;; 
-;; define i1 @icmp_ugt_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
-;; entry:
-;;        %A = icmp ugt i64 %arg1, %arg2
-;;        ret i1 %A
-;; }
-;; 
+define i64 @icmp_ugt_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
+entry:
+       %A = icmp ugt i64 %arg1, %arg2
+       %B = select i1 %A, i64 %val1, i64 %val2
+       ret i64 %B
+}
+
+define i1 @icmp_ugt_setcc_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
+entry:
+       %A = icmp ugt i64 %arg1, %arg2
+       ret i1 %A
+}
+
 ;; define i64 @icmp_uge_select_i64(i64 %arg1, i64 %arg2, i64 %val1, i64 %val2) nounwind {
 ;; entry:
 ;;        %A = icmp uge i64 %arg1, %arg2
diff --git a/test/CodeGen/CellSPU/useful-harnesses/i64operations.c b/test/CodeGen/CellSPU/useful-harnesses/i64operations.c
index 3819797..a2e7a9f 100644
--- a/test/CodeGen/CellSPU/useful-harnesses/i64operations.c
+++ b/test/CodeGen/CellSPU/useful-harnesses/i64operations.c
@@ -1,71 +1,293 @@
 #include <stdio.h>
 
-typedef unsigned long long int	uint64_t;
-typedef long long int   	int64_t;
+#define TRUE_VAL (!0)
+#define FALSE_VAL 0
+#define ARR_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
 
-const char *boolstring(int val) {
-  return val ? "true" : "false";
-}
+typedef unsigned long long int uint64_t;
+typedef long long int int64_t;
 
-int i64_eq(int64_t a, int64_t b) {
+/* ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- */
+
+int64_t         a = 1234567890003LL;
+int64_t         b = 2345678901235LL;
+int64_t         c = 1234567890001LL;
+int64_t         d = 10001LL;
+int64_t         e = 10000LL;
+int64_t         f = -1068103409991LL;
+
+/* ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- */
+
+int 
+i64_eq(int64_t a, int64_t b)
+{
   return (a == b);
 }
 
-int i64_neq(int64_t a, int64_t b) {
+int 
+i64_neq(int64_t a, int64_t b)
+{
   return (a != b);
 }
 
-int64_t i64_eq_select(int64_t a, int64_t b, int64_t c, int64_t d) {
+int 
+i64_ugt(uint64_t a, uint64_t b)
+{
+  return (a > b);
+}
+
+int 
+i64_ule(uint64_t a, uint64_t b)
+{
+  return (a <= b);
+}
+
+int64_t 
+i64_eq_select(int64_t a, int64_t b, int64_t c, int64_t d)
+{
   return ((a == b) ? c : d);
 }
 
-int64_t i64_neq_select(int64_t a, int64_t b, int64_t c, int64_t d) {
+int64_t 
+i64_neq_select(int64_t a, int64_t b, int64_t c, int64_t d)
+{
   return ((a != b) ? c : d);
 }
 
-struct pred_s {
-  const char   *name;
-  int 		(*predfunc)(int64_t, int64_t);
-  int64_t       (*selfunc)(int64_t, int64_t, int64_t, int64_t);
+uint64_t 
+i64_ugt_select(uint64_t a, uint64_t b, uint64_t c, uint64_t d)
+{
+  return ((a > b) ? c : d);
+}
+
+uint64_t 
+i64_ule_select(uint64_t a, uint64_t b, uint64_t c, uint64_t d)
+{
+  return ((a <= b) ? c : d);
+}
+
+/* ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- */
+
+struct harness_int64_pred {
+  const char     *fmt_string;
+  int64_t        *lhs;
+  int64_t        *rhs;
+  int64_t        *select_a;
+  int64_t        *select_b;
+  int             expected;
+  int64_t        *select_expected;
 };
 
-struct pred_s preds[] = {
-  { "eq",  i64_eq,  i64_eq_select },
-  { "neq", i64_neq, i64_neq_select }
+struct harness_uint64_pred {
+  const char     *fmt_string;
+  uint64_t       *lhs;
+  uint64_t       *rhs;
+  uint64_t       *select_a;
+  uint64_t       *select_b;
+  int             expected;
+  uint64_t       *select_expected;
 };
 
-uint64_t i64_shl_const(uint64_t a) {
+struct int64_pred_s {
+  const char     *name;
+  int             (*predfunc) (int64_t, int64_t);
+  int64_t         (*selfunc) (int64_t, int64_t, int64_t, int64_t);
+  struct harness_int64_pred *tests;
+  int             n_tests;
+};
+
+struct uint64_pred_s {
+  const char     *name;
+  int             (*predfunc) (uint64_t, uint64_t);
+  uint64_t        (*selfunc) (uint64_t, uint64_t, uint64_t, uint64_t);
+  struct harness_uint64_pred *tests;
+  int             n_tests;
+};
+
+/* ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- */
+
+struct harness_int64_pred int64_tests_eq[] = {
+  {"a %s a", &a, &a, &c, &d, TRUE_VAL, &c},
+  {"a %s b", &a, &b, &c, &d, FALSE_VAL, &d},
+  {"a %s c", &a, &c, &c, &d, FALSE_VAL, &d},
+  {"d %s e", &d, &e, &c, &d, FALSE_VAL, &d},
+  {"e %s e", &e, &e, &c, &d, TRUE_VAL, &c}
+};
+
+struct harness_int64_pred int64_tests_neq[] = {
+  {"a %s a", &a, &a, &c, &d, FALSE_VAL, &d},
+  {"a %s b", &a, &b, &c, &d, TRUE_VAL, &c},
+  {"a %s c", &a, &c, &c, &d, TRUE_VAL, &c},
+  {"d %s e", &d, &e, &c, &d, TRUE_VAL, &c},
+  {"e %s e", &e, &e, &c, &d, FALSE_VAL, &d}
+};
+
+struct int64_pred_s int64_preds[] = {
+  {"eq", i64_eq, i64_eq_select,
+     int64_tests_eq, ARR_SIZE(int64_tests_eq)},
+  {"neq", i64_neq, i64_neq_select,
+     int64_tests_neq, ARR_SIZE(int64_tests_neq)}
+};
+
+/* ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- */
+
+struct harness_uint64_pred uint64_tests_ugt[] = {
+  {"a %s a", (uint64_t *) &a, (uint64_t *) &a, (uint64_t *) &c,
+     (uint64_t *) &d, FALSE_VAL, (uint64_t *) &d},
+  {"a %s b", (uint64_t *) &a, (uint64_t *) &b, (uint64_t *) &c,
+     (uint64_t *) &d, FALSE_VAL, (uint64_t *) &d },
+  {"a %s c", (uint64_t *) &a, (uint64_t *) &c, (uint64_t *) &c,
+     (uint64_t *) &d, TRUE_VAL, (uint64_t *) &c },
+  {"d %s e", (uint64_t *) &d, (uint64_t *) &e, (uint64_t *) &c,
+     (uint64_t *) &d, TRUE_VAL, (uint64_t *) &c },
+  {"e %s e", (uint64_t *) &e, (uint64_t *) &e, (uint64_t *) &c,
+     (uint64_t *) &d, FALSE_VAL, (uint64_t *) &d }
+};
+
+struct harness_uint64_pred uint64_tests_ule[] = {
+  {"a %s a", (uint64_t *) &a, (uint64_t *) &a, (uint64_t *) &c,
+     (uint64_t *) &d, TRUE_VAL, (uint64_t *) &c},
+  {"a %s b", (uint64_t *) &a, (uint64_t *) &b, (uint64_t *) &c,
+     (uint64_t *) &d, TRUE_VAL, (uint64_t *) &c},
+  {"a %s c", (uint64_t *) &a, (uint64_t *) &c, (uint64_t *) &c,
+     (uint64_t *) &d, FALSE_VAL, (uint64_t *) &d},
+  {"d %s e", (uint64_t *) &d, (uint64_t *) &e, (uint64_t *) &c,
+     (uint64_t *) &d, FALSE_VAL, (uint64_t *) &d},
+  {"e %s e", (uint64_t *) &e, (uint64_t *) &e, (uint64_t *) &c,
+     (uint64_t *) &d, TRUE_VAL, (uint64_t *) &c}
+};
+
+struct uint64_pred_s uint64_preds[] = {
+  {"ugt", i64_ugt, i64_ugt_select,
+     uint64_tests_ugt, ARR_SIZE(uint64_tests_ugt)},
+  {"ule", i64_ule, i64_ule_select,
+     uint64_tests_ule, ARR_SIZE(uint64_tests_ule)}
+};
+
+int 
+compare_expect_int64(const struct int64_pred_s * pred)
+{
+  int             j, failed = 0;
+
+  for (j = 0; j < pred->n_tests; ++j) {
+    int             pred_result =
+    (*pred->predfunc) (*pred->tests[j].lhs, *pred->tests[j].rhs);
+
+    if (pred_result != pred->tests[j].expected) {
+      char            str[64];
+
+      sprintf(str, pred->tests[j].fmt_string, pred->name);
+      printf("%s: returned value is %d, expecting %d\n", str,
+	     pred_result, pred->tests[j].expected);
+      printf("  lhs = %19lld (0x%016llx)\n", *pred->tests[j].lhs, *pred->tests[j].lhs);
+      printf("  rhs = %19lld (0x%016llx)\n", *pred->tests[j].rhs, *pred->tests[j].rhs);
+      ++failed;
+    } else {
+      int64_t         selresult = (pred->selfunc) (*pred->tests[j].lhs, *pred->tests[j].rhs,
+			  *pred->tests[j].select_a, *pred->tests[j].select_b);
+      if (selresult != *pred->tests[j].select_expected) {
+	char            str[64];
+
+	sprintf(str, pred->tests[j].fmt_string, pred->name);
+	printf("%s select: returned value is %d, expecting %d\n", str,
+	       pred_result, pred->tests[j].expected);
+	printf("  lhs   = %19lld (0x%016llx)\n", *pred->tests[j].lhs, *pred->tests[j].lhs);
+	printf("  rhs   = %19lld (0x%016llx)\n", *pred->tests[j].rhs, *pred->tests[j].rhs);
+	printf("  true  = %19lld (0x%016llx)\n", *pred->tests[j].select_a, *pred->tests[j].select_a);
+	printf("  false = %19lld (0x%016llx)\n", *pred->tests[j].select_b, *pred->tests[j].select_b);
+	++failed;
+      }
+    }
+  }
+
+  return failed;
+}
+
+int 
+compare_expect_uint64(const struct uint64_pred_s * pred)
+{
+  int             j, failed = 0;
+
+  for (j = 0; j < pred->n_tests; ++j) {
+    int             pred_result = (*pred->predfunc) (*pred->tests[j].lhs, *pred->tests[j].rhs);
+
+    if (pred_result != pred->tests[j].expected) {
+      char            str[64];
+
+      sprintf(str, pred->tests[j].fmt_string, pred->name);
+      printf("%s: returned value is %d, expecting %d\n", str,
+	     pred_result, pred->tests[j].expected);
+      printf("  lhs = %19llu (0x%016llx)\n", *pred->tests[j].lhs, *pred->tests[j].lhs);
+      printf("  rhs = %19llu (0x%016llx)\n", *pred->tests[j].rhs, *pred->tests[j].rhs);
+      ++failed;
+    } else {
+      uint64_t        selresult = (pred->selfunc) (*pred->tests[j].lhs, *pred->tests[j].rhs,
+			  *pred->tests[j].select_a, *pred->tests[j].select_b);
+      if (selresult != *pred->tests[j].select_expected) {
+	char            str[64];
+
+	sprintf(str, pred->tests[j].fmt_string, pred->name);
+	printf("%s select: returned value is %d, expecting %d\n", str,
+	       pred_result, pred->tests[j].expected);
+	printf("  lhs   = %19llu (0x%016llx)\n", *pred->tests[j].lhs, *pred->tests[j].lhs);
+	printf("  rhs   = %19llu (0x%016llx)\n", *pred->tests[j].rhs, *pred->tests[j].rhs);
+	printf("  true  = %19llu (0x%016llx)\n", *pred->tests[j].select_a, *pred->tests[j].select_a);
+	printf("  false = %19llu (0x%016llx)\n", *pred->tests[j].select_b, *pred->tests[j].select_b);
+	++failed;
+      }
+    }
+
+  }
+
+  return failed;
+}
+
+/* ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- */
+
+uint64_t 
+i64_shl_const(uint64_t a)
+{
   return a << 10;
 }
 
-uint64_t i64_shl(uint64_t a, int amt) {
+uint64_t 
+i64_shl(uint64_t a, int amt)
+{
   return a << amt;
 }
 
-uint64_t i64_srl_const(uint64_t a) {
+uint64_t 
+i64_srl_const(uint64_t a)
+{
   return a >> 10;
 }
 
-uint64_t i64_srl(uint64_t a, int amt) {
+uint64_t 
+i64_srl(uint64_t a, int amt)
+{
   return a >> amt;
 }
 
-int64_t i64_sra_const(int64_t a) {
+int64_t 
+i64_sra_const(int64_t a)
+{
   return a >> 10;
 }
 
-int64_t i64_sra(int64_t a, int amt) {
+int64_t 
+i64_sra(int64_t a, int amt)
+{
   return a >> amt;
 }
 
-int main(void) {
-  int i;
-  int64_t a =  1234567890003LL;
-  int64_t b =  2345678901235LL;
-  int64_t c =  1234567890001LL;
-  int64_t d =          10001LL;
-  int64_t e =          10000LL;
-  int64_t f = -1068103409991LL;
+/* ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- */
+
+int 
+main(void)
+{
+  int             i, j, failed = 0;
+  const char     *something_failed = "  %d tests failed.\n";
+  const char     *all_tests_passed = "  All tests passed.\n";
 
   printf("a = %16lld (0x%016llx)\n", a, a);
   printf("b = %16lld (0x%016llx)\n", b, b);
@@ -75,28 +297,35 @@
   printf("f = %16lld (0x%016llx)\n", f, f);
   printf("----------------------------------------\n");
 
-  for (i = 0; i < sizeof(preds)/sizeof(preds[0]); ++i) {
-    printf("a %s a = %s\n", preds[i].name, boolstring((*preds[i].predfunc)(a, a)));
-    printf("a %s b = %s\n", preds[i].name, boolstring((*preds[i].predfunc)(a, b)));
-    printf("a %s c = %s\n", preds[i].name, boolstring((*preds[i].predfunc)(a, c)));
-    printf("d %s e = %s\n", preds[i].name, boolstring((*preds[i].predfunc)(d, e)));
-    printf("e %s e = %s\n", preds[i].name, boolstring((*preds[i].predfunc)(e, e)));
+  for (i = 0; i < ARR_SIZE(int64_preds); ++i) {
+    printf("%s series:\n", int64_preds[i].name);
+    if ((failed = compare_expect_int64(int64_preds + i)) > 0) {
+      printf(something_failed, failed);
+    } else {
+      printf(all_tests_passed);
+    }
 
-    printf("a %s a ? c : d = %lld\n", preds[i].name, (*preds[i].selfunc)(a, a, c, d));
-    printf("a %s a ? c : d == c (%s)\n", preds[i].name, boolstring((*preds[i].selfunc)(a, a, c, d) == c));
-    printf("a %s b ? c : d = %lld\n", preds[i].name, (*preds[i].selfunc)(a, b, c, d));
-    printf("a %s b ? c : d == d (%s)\n", preds[i].name, boolstring((*preds[i].selfunc)(a, b, c, d) == d));
+    printf("----------------------------------------\n");
+  }
+
+  for (i = 0; i < ARR_SIZE(uint64_preds); ++i) {
+    printf("%s series:\n", uint64_preds[i].name);
+    if ((failed = compare_expect_uint64(uint64_preds + i)) > 0) {
+      printf(something_failed, failed);
+    } else {
+      printf(all_tests_passed);
+    }
 
     printf("----------------------------------------\n");
   }
 
   printf("a                = 0x%016llx\n", a);
   printf("i64_shl_const(a) = 0x%016llx\n", i64_shl_const(a));
-  printf("i64_shl(a)       = 0x%016llx\n", i64_shl(a, 5));
+  printf("i64_shl(a)       = 0x%016llx\n", i64_shl(a, 10));
   printf("i64_srl_const(a) = 0x%016llx\n", i64_srl_const(a));
-  printf("i64_srl(a)       = 0x%016llx\n", i64_srl(a, 5));
+  printf("i64_srl(a)       = 0x%016llx\n", i64_srl(a, 10));
   printf("i64_sra_const(a) = 0x%016llx\n", i64_sra_const(a));
-  printf("i64_sra(a)       = 0x%016llx\n", i64_sra(a, 5));
+  printf("i64_sra(a)       = 0x%016llx\n", i64_sra(a, 10));
   printf("----------------------------------------\n");
 
   printf("f                = 0x%016llx\n", f);