[llvm-commits] [llvm] r61664 - in /llvm/trunk: lib/Target/CellSPU/SPU64InstrInfo.td lib/Target/CellSPU/SPUInstrInfo.td lib/Target/CellSPU/SPUNodes.td test/CodeGen/CellSPU/icmp64.ll test/CodeGen/CellSPU/useful-harnesses/i64operations.c

Scott Michel scottm at aero.org
Sun Jan 4 17:34:35 PST 2009


Author: pingbak
Date: Sun Jan  4 19:34:35 2009
New Revision: 61664

URL: http://llvm.org/viewvc/llvm-project?rev=61664&view=rev
Log:
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.

Modified:
    llvm/trunk/lib/Target/CellSPU/SPU64InstrInfo.td
    llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td
    llvm/trunk/lib/Target/CellSPU/SPUNodes.td
    llvm/trunk/test/CodeGen/CellSPU/icmp64.ll
    llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/i64operations.c

Modified: llvm/trunk/lib/Target/CellSPU/SPU64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPU64InstrInfo.td?rev=61664&r1=61663&r2=61664&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPU64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/CellSPU/SPU64InstrInfo.td Sun Jan  4 19:34:35 2009
@@ -22,6 +22,9 @@
 // 4. v2i64 setcc results are v4i32, which can be converted to a FSM mask (TODO)
 //    [Note: this may be moot, since gb produces v4i32 or r32.]
 //
+// 5. The code sequences for r64 and v2i64 are probably overly conservative,
+//    compared to the code that gcc produces.
+//
 // M00$E B!tes Kan be Pretty N at sTi!!!!! (appologies to Monty!)
 //-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
 
@@ -41,18 +44,23 @@
   Pat<(cond R64C:$rA, R64C:$rB),
       (XORIr32 compare.Fragment, -1)>;
 
+// The generic i64 select pattern, which assumes that the comparison result
+// is in a 32-bit register that contains a select mask pattern (i.e., gather
+// bits result):
+
+def : Pat<(select R32C:$rC, R64C:$rB, R64C:$rA),
+          (SELBr64_cond R64C:$rA, R64C:$rB, (FSMr32 R32C:$rC))>;
+
+//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
 // The i64 seteq fragment that does the scalar->vector conversion and
 // comparison:
 def CEQr64compare:
     CodeFrag<(CGTIv4i32 (GBv4i32 (CEQv4i32 (ORv2i64_i64 R64C:$rA),
-                                           (ORv2i64_i64 R64C:$rB))),
-                        0x0000000c)>;
-
+                                           (ORv2i64_i64 R64C:$rB))), 0xb)>;
 
 // The i64 seteq fragment that does the vector comparison
 def CEQv2i64compare:
-    CodeFrag<(CGTIv4i32 (GBv4i32 (CEQv4i32 VECREG:$rA, VECREG:$rB)),
-                        0x0000000f)>;
+    CodeFrag<(CEQIv4i32 (GBv4i32 (CEQv4i32 VECREG:$rA, VECREG:$rB)), 0xf)>;
 
 // i64 seteq (equality): the setcc result is i32, which is converted to a
 // vector FSM mask when used in a select pattern.
@@ -73,11 +81,52 @@
 def : Pat<(seteq R64C:$rA, R64C:$rB), I64EQr64.Fragment>;
 def : Pat<(seteq (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)), I64EQv2i64.Fragment>;
 
-def : Pat<(select R32C:$rC, R64C:$rB, R64C:$rA),
-          (SELBr64_cond R64C:$rA, R64C:$rB, (FSMr32 R32C:$rC))>;
-
 // i64 setne:
 def : I64SETCCNegCond<setne, I64EQr64>;
 def : I64SELECTNegCond<setne, I64EQr64>;
 
+//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
 // i64 setugt:
+//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
+
+def CLGTr64ugt:
+    CodeFrag<(CLGTv4i32 (ORv2i64_i64 R64C:$rA), (ORv2i64_i64 R64C:$rB))>;
+
+def CLGTr64eq:
+    CodeFrag<(CEQv4i32 (ORv2i64_i64 R64C:$rA), (ORv2i64_i64 R64C:$rB))>;
+    
+def CLGTr64compare:
+    CodeFrag<(SELBv2i64 CLGTr64ugt.Fragment,
+                        (XSWDv2i64 CLGTr64ugt.Fragment),
+                        CLGTr64eq.Fragment)>;
+
+def CLGTv2i64ugt:
+    CodeFrag<(CLGTv4i32 VECREG:$rA, VECREG:$rB)>;
+
+def CLGTv2i64eq:
+    CodeFrag<(CEQv4i32 VECREG:$rA, VECREG:$rB)>;
+    
+def CLGTv2i64compare:
+    CodeFrag<(SELBv2i64 CLGTv2i64ugt.Fragment,
+                        (XSWDv2i64 CLGTr64ugt.Fragment),
+                        CLGTv2i64eq.Fragment)>;
+
+multiclass CompareLogicalGreaterThan64 {
+  // Plain old comparison, converts back to i32 scalar
+  def r64: CodeFrag<(ORi32_v4i32 CLGTr64compare.Fragment)>;
+  def v2i64: CodeFrag<CLGTv2i64compare.Fragment>;
+
+  // SELB mask from FSM:
+  def r64mask: CodeFrag<(ORi32_v4i32 (FSMv4i32 CLGTr64compare.Fragment))>;
+  def v2i64mask: CodeFrag<(ORi32_v4i32 (FSMv4i32 CLGTv2i64compare.Fragment))>;
+}
+
+defm I64LGT: CompareLogicalGreaterThan64;
+
+def : Pat<(setugt R64C:$rA, R64C:$rB), I64LGTr64.Fragment>;
+def : Pat<(setugt (v2i64 VECREG:$rA), (v2i64 VECREG:$rB)),
+                  I64LGTv2i64.Fragment>;
+
+// i64 setult:
+def : I64SETCCNegCond<setule, I64LGTr64>;
+def : I64SELECTNegCond<setule, I64LGTr64>;

Modified: llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td?rev=61664&r1=61663&r2=61664&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUInstrInfo.td Sun Jan  4 19:34:35 2009
@@ -1176,23 +1176,31 @@
       "xshw\t$rDst, $rSrc", IntegerOp,
       [(set R32C:$rDst, (sext R16C:$rSrc))]>;
 
-def XSWDvec:
-    RRForm_1<0b01100101010, (outs VECREG:$rDst), (ins VECREG:$rSrc),
-      "xswd\t$rDst, $rSrc", IntegerOp,
-      [(set (v2i64 VECREG:$rDst), (sext (v4i32 VECREG:$rSrc)))]>;
-
-def XSWDr64:
-    RRForm_1<0b01100101010, (outs R64C:$rDst), (ins R64C:$rSrc),
-      "xswd\t$rDst, $rSrc", IntegerOp,
-      [(set R64C:$rDst, (sext_inreg R64C:$rSrc, i32))]>;
+// Sign-extend words to doublewords (32->64 bits)
 
-def XSWDr32:
-    RRForm_1<0b01100101010, (outs R64C:$rDst), (ins R32C:$rSrc),
+class XSWDInst<dag OOL, dag IOL, list<dag> pattern>:
+    RRForm_1<0b01100101010, OOL, IOL,
       "xswd\t$rDst, $rSrc", IntegerOp,
-      [(set R64C:$rDst, (SPUsext32_to_64 R32C:$rSrc))]>;
+      pattern>;
+      
+class XSWDVecInst<ValueType in_vectype, ValueType out_vectype>:
+    XSWDInst<(outs VECREG:$rDst), (ins VECREG:$rSrc),
+             [(set (out_vectype VECREG:$rDst),
+                   (sext (out_vectype VECREG:$rSrc)))]>;
+      
+class XSWDRegInst<RegisterClass in_rclass, RegisterClass out_rclass>:
+    XSWDInst<(outs out_rclass:$rDst), (ins in_rclass:$rSrc),
+             [(set out_rclass:$rDst, (sext in_rclass:$rSrc))]>;
+             
+multiclass ExtendWordToDoubleWord {
+  def v2i64: XSWDVecInst<v4i32, v2i64>;
+  def r64:   XSWDRegInst<R32C, R64C>;
+  
+  def r64_inreg: XSWDInst<(outs R64C:$rDst), (ins R64C:$rSrc),
+                          [(set R64C:$rDst, (sext_inreg R64C:$rSrc, i32))]>;
+}
 
-def : Pat<(sext R32C:$inp),
-          (XSWDr32 R32C:$inp)>;
+defm XSWD : ExtendWordToDoubleWord;
 
 // AND operations
 
@@ -3511,7 +3519,7 @@
   def BI:
     BIForm<0b00010101100, "bi\t$func", [(brind R32C:$func)]>;
 
-  // Various branches:
+  // Conditional branches:
   class BRNZInst<dag IOL, list<dag> pattern>:
     RI16Form<0b010000100, (outs), IOL, "brnz\t$rCond,$dest",
              BranchResolv, pattern>;
@@ -3651,8 +3659,8 @@
                 (brinst32 (CEQr32 R32C:$rA, R32C:$rB), bb:$dest)>;
 }
 
-defm BRCONDeq : BranchCondEQ<seteq, BRHZr16, BRZr32>;
-defm BRCONDne : BranchCondEQ<setne, BRHNZr16, BRNZr32>;
+defm BRCONDeq : BranchCondEQ<seteq, BRHNZr16, BRNZr32>;
+defm BRCONDne : BranchCondEQ<setne, BRHZr16, BRZr32>;
 
 multiclass BranchCondLGT<PatFrag cond, SPUInstr brinst16, SPUInstr brinst32>
 {

Modified: llvm/trunk/lib/Target/CellSPU/SPUNodes.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CellSPU/SPUNodes.td?rev=61664&r1=61663&r2=61664&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CellSPU/SPUNodes.td (original)
+++ llvm/trunk/lib/Target/CellSPU/SPUNodes.td Sun Jan  4 19:34:35 2009
@@ -137,16 +137,6 @@
 // Indirect [D-Form "imm($reg)" and X-Form "$reg($reg)"] addresses
 def SPUindirect : SDNode<"SPUISD::IndirectAddr", SDTIntBinOp, []>;
 
-// SPU 32-bit sign-extension to 64-bits
-def SPUsext32_to_64: SDNode<"SPUISD::SEXT32TO64", SDTIntExtendOp, []>;
-
-// Branches:
-
-def SPUbrnz : SDNode<"SPUISD::BR_NOTZERO", SDTBrcond,  [SDNPHasChain]>;
-def SPUbrz  : SDNode<"SPUISD::BR_ZERO",    SDTBrcond,  [SDNPHasChain]>;
-/* def SPUbinz : SDNode<"SPUISD::BR_NOTZERO", SDTBrind,   [SDNPHasChain]>;
-def SPUbiz  : SDNode<"SPUISD::BR_ZERO",    SPUBrind,   [SDNPHasChain]>; */
-
 //===----------------------------------------------------------------------===//
 // Constraints: (taken from PPCInstrInfo.td)
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/test/CodeGen/CellSPU/icmp64.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/icmp64.ll?rev=61664&r1=61663&r2=61664&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/icmp64.ll (original)
+++ llvm/trunk/test/CodeGen/CellSPU/icmp64.ll Sun Jan  4 19:34:35 2009
@@ -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

Modified: llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/i64operations.c
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/i64operations.c?rev=61664&r1=61663&r2=61664&view=diff

==============================================================================
--- llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/i64operations.c (original)
+++ llvm/trunk/test/CodeGen/CellSPU/useful-harnesses/i64operations.c Sun Jan  4 19:34:35 2009
@@ -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]))
+
+typedef unsigned long long int uint64_t;
+typedef long long int int64_t;
+
+/* ~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~- */
+
+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);
+}
 
-const char *boolstring(int val) {
-  return val ? "true" : "false";
+int 
+i64_neq(int64_t a, int64_t b)
+{
+  return (a != b);
 }
 
-int i64_eq(int64_t a, int64_t b) {
-  return (a == b);
+int 
+i64_ugt(uint64_t a, uint64_t b)
+{
+  return (a > b);
 }
 
-int i64_neq(int64_t a, int64_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) {
+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 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;
+};
+
+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 pred_s preds[] = {
-  { "eq",  i64_eq,  i64_eq_select },
-  { "neq", i64_neq, i64_neq_select }
+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}
 };
 
-uint64_t i64_shl_const(uint64_t a) {
+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)));
-
-    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));
+  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("----------------------------------------\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);





More information about the llvm-commits mailing list