poke-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[COMMITTED] pkl: support equality and inequality of `any' values


From: Jose E. Marchesi
Subject: [COMMITTED] pkl: support equality and inequality of `any' values
Date: Fri, 03 Feb 2023 01:01:49 +0100
User-agent: Gnus/5.13 (Gnus v5.13)

This commit adds support for comparing values of type `any' with the
== and != operators.

Type dispatching is performed at run-time dynamically.  All different
combinations are supported.

This is useful by itself, and also a requirement to support `any'
fields in structs.

2023-02-03  Jose E. Marchesi  <jemarch@gnu.org>

        * libpoke/pkl-rt.pk (_pkl_64x64_128): New function.
        (_pkl_any_integral_p): Likewise.
        (_pkl_eq_integral): Likewise.
        (_pkl_eq_offset): Likewise.
        (_pkl_eq_array): Likewise.
        (_pkl_eq_struct): Likewise.
        (_pkl_eq_any): Likewise.
        * libpoke/pkl-gen.c (pkl_gen_ps_op_rela): Support EQ and NE for
        `any' values.
        (pkl_gen_pr_cast): Do nothing for casts to `any'.
        * libpoke/pkl-typify.c (pkl_typify1_ps_op_rela): Likewise.
        * libpoke/pkl-promo.c (pkl_promo_ps_op_rela): Likewise.
        (promote_to_any): New function.
        * testsuite/poke.pkl/eq-any-diag-1.pk: Remove test.
        * testsuite/poke.pkl/neq-any-diag-1.pk: Likewise.
        * testsuite/poke.pkl/ge-any-diag-1.pk: New test.
        * testsuite/poke.pkl/le-any-diag-1.pk: Likewise.
        * testsuite/poke.pkl/lt-any-diag-1.pk: Likewise.
        * testsuite/poke.pkl/gt-any-diag-1.pk: Likewise.
        * testsuite/poke.pkl/eq-any-integral-1.pk: Likewise.
        * testsuite/poke.pkl/eq-any-integral-2.pk: Likewise.
        * testsuite/poke.pkl/eq-any-integral-3.pk: Likewise.
        * testsuite/poke.pkl/eq-any-integral-4.pk: Likewise.
        * testsuite/poke.pkl/eq-any-offset-1.pk: Likewise.
        * testsuite/poke.pkl/eq-any-offset-2.pk: Likewise.
        * testsuite/poke.pkl/eq-any-offset-3.pk: Likewise.
        * testsuite/poke.pkl/eq-any-offset-4.pk: Likewise.
        * testsuite/poke.pkl/eq-any-offset-5.pk: Likewise.
        * testsuite/poke.pkl/eq-any-offset-6.pk: Likewise.
        * testsuite/poke.pkl/eq-any-offset-7.pk: Likewise.
        * testsuite/poke.pkl/neq-any-offset-1.pk: Likewise.
        * testsuite/poke.pkl/neq-any-offset-2.pk: Likewise.
        * testsuite/poke.pkl/neq-any-offset-3.pk: Likewise.
        * testsuite/poke.pkl/neq-any-offset-4.pk: Likewise.
        * testsuite/poke.pkl/neq-any-offset-5.pk: Likewise.
        * testsuite/poke.pkl/neq-any-offset-6.pk: Likewise.
        * testsuite/poke.pkl/neq-any-offset-7.pk: Likewise.
        * testsuite/poke.pkl/eq-any-array-1.pk: Likewise.
        * testsuite/poke.pkl/eq-any-array-2.pk: Likewise.
        * testsuite/poke.pkl/neq-any-array-1.pk: Likewise.
        * testsuite/poke.pkl/neq-any-array-2.pk: Likewise.
        * testsuite/poke.pkl/eq-any-string-1.pk: Likewise.
        * testsuite/poke.pkl/neq-any-string-1.pk: Likewise.
        * testsuite/poke.pkl/eq-any-struct-1.pk: Likewise.
        * testsuite/poke.pkl/eq-any-struct-2.pk: Likewise.
        * testsuite/poke.pkl/eq-any-struct-3.pk: Likewise.
        * testsuite/poke.pkl/eq-any-struct-4.pk: Likewise.
        * testsuite/poke.pkl/neq-any-struct-1.pk: Likewise.
        * testsuite/poke.pkl/neq-any-struct-2.pk: Likewise.
        * testsuite/Makefile.am (EXTRA_DIST): Update.
---
 ChangeLog                               |  53 +++++
 libpoke/pkl-gen.c                       |  13 ++
 libpoke/pkl-promo.c                     |  37 +++-
 libpoke/pkl-rt.pk                       | 274 ++++++++++++++++++++++++
 libpoke/pkl-typify.c                    |  13 +-
 testsuite/Makefile.am                   |  36 +++-
 testsuite/poke.pkl/eq-any-array-1.pk    |  18 ++
 testsuite/poke.pkl/eq-any-array-2.pk    |  12 ++
 testsuite/poke.pkl/eq-any-diag-1.pk     |   6 -
 testsuite/poke.pkl/eq-any-integral-1.pk |  31 +++
 testsuite/poke.pkl/eq-any-integral-2.pk |  31 +++
 testsuite/poke.pkl/eq-any-integral-3.pk |  31 +++
 testsuite/poke.pkl/eq-any-integral-4.pk |  31 +++
 testsuite/poke.pkl/eq-any-offset-1.pk   |   6 +
 testsuite/poke.pkl/eq-any-offset-2.pk   |   6 +
 testsuite/poke.pkl/eq-any-offset-3.pk   |   6 +
 testsuite/poke.pkl/eq-any-offset-4.pk   |   6 +
 testsuite/poke.pkl/eq-any-offset-5.pk   |   6 +
 testsuite/poke.pkl/eq-any-offset-6.pk   |   6 +
 testsuite/poke.pkl/eq-any-offset-7.pk   |   6 +
 testsuite/poke.pkl/eq-any-string-1.pk   |  12 ++
 testsuite/poke.pkl/eq-any-struct-1.pk   |  11 +
 testsuite/poke.pkl/eq-any-struct-2.pk   |  19 ++
 testsuite/poke.pkl/eq-any-struct-3.pk   |  20 ++
 testsuite/poke.pkl/eq-any-struct-4.pk   |  21 ++
 testsuite/poke.pkl/ge-any-diag-1.pk     |   6 +
 testsuite/poke.pkl/gt-any-diag-1.pk     |   6 +
 testsuite/poke.pkl/le-any-diag-1.pk     |   6 +
 testsuite/poke.pkl/lt-any-diag-1.pk     |   6 +
 testsuite/poke.pkl/neq-any-array-1.pk   |  15 ++
 testsuite/poke.pkl/neq-any-array-2.pk   |  12 ++
 testsuite/poke.pkl/neq-any-diag-1.pk    |   6 -
 testsuite/poke.pkl/neq-any-offset-1.pk  |   6 +
 testsuite/poke.pkl/neq-any-offset-2.pk  |   6 +
 testsuite/poke.pkl/neq-any-offset-3.pk  |   6 +
 testsuite/poke.pkl/neq-any-offset-4.pk  |   6 +
 testsuite/poke.pkl/neq-any-offset-5.pk  |   6 +
 testsuite/poke.pkl/neq-any-offset-6.pk  |   6 +
 testsuite/poke.pkl/neq-any-offset-7.pk  |   6 +
 testsuite/poke.pkl/neq-any-string-1.pk  |  12 ++
 testsuite/poke.pkl/neq-any-struct-1.pk  |  11 +
 testsuite/poke.pkl/neq-any-struct-2.pk  |  19 ++
 42 files changed, 832 insertions(+), 20 deletions(-)
 create mode 100644 testsuite/poke.pkl/eq-any-array-1.pk
 create mode 100644 testsuite/poke.pkl/eq-any-array-2.pk
 delete mode 100644 testsuite/poke.pkl/eq-any-diag-1.pk
 create mode 100644 testsuite/poke.pkl/eq-any-integral-1.pk
 create mode 100644 testsuite/poke.pkl/eq-any-integral-2.pk
 create mode 100644 testsuite/poke.pkl/eq-any-integral-3.pk
 create mode 100644 testsuite/poke.pkl/eq-any-integral-4.pk
 create mode 100644 testsuite/poke.pkl/eq-any-offset-1.pk
 create mode 100644 testsuite/poke.pkl/eq-any-offset-2.pk
 create mode 100644 testsuite/poke.pkl/eq-any-offset-3.pk
 create mode 100644 testsuite/poke.pkl/eq-any-offset-4.pk
 create mode 100644 testsuite/poke.pkl/eq-any-offset-5.pk
 create mode 100644 testsuite/poke.pkl/eq-any-offset-6.pk
 create mode 100644 testsuite/poke.pkl/eq-any-offset-7.pk
 create mode 100644 testsuite/poke.pkl/eq-any-string-1.pk
 create mode 100644 testsuite/poke.pkl/eq-any-struct-1.pk
 create mode 100644 testsuite/poke.pkl/eq-any-struct-2.pk
 create mode 100644 testsuite/poke.pkl/eq-any-struct-3.pk
 create mode 100644 testsuite/poke.pkl/eq-any-struct-4.pk
 create mode 100644 testsuite/poke.pkl/ge-any-diag-1.pk
 create mode 100644 testsuite/poke.pkl/gt-any-diag-1.pk
 create mode 100644 testsuite/poke.pkl/le-any-diag-1.pk
 create mode 100644 testsuite/poke.pkl/lt-any-diag-1.pk
 create mode 100644 testsuite/poke.pkl/neq-any-array-1.pk
 create mode 100644 testsuite/poke.pkl/neq-any-array-2.pk
 delete mode 100644 testsuite/poke.pkl/neq-any-diag-1.pk
 create mode 100644 testsuite/poke.pkl/neq-any-offset-1.pk
 create mode 100644 testsuite/poke.pkl/neq-any-offset-2.pk
 create mode 100644 testsuite/poke.pkl/neq-any-offset-3.pk
 create mode 100644 testsuite/poke.pkl/neq-any-offset-4.pk
 create mode 100644 testsuite/poke.pkl/neq-any-offset-5.pk
 create mode 100644 testsuite/poke.pkl/neq-any-offset-6.pk
 create mode 100644 testsuite/poke.pkl/neq-any-offset-7.pk
 create mode 100644 testsuite/poke.pkl/neq-any-string-1.pk
 create mode 100644 testsuite/poke.pkl/neq-any-struct-1.pk
 create mode 100644 testsuite/poke.pkl/neq-any-struct-2.pk

diff --git a/ChangeLog b/ChangeLog
index b8dddfed..becafbc7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,56 @@
+2023-02-03  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * libpoke/pkl-rt.pk (_pkl_64x64_128): New function.
+       (_pkl_any_integral_p): Likewise.
+       (_pkl_eq_integral): Likewise.
+       (_pkl_eq_offset): Likewise.
+       (_pkl_eq_array): Likewise.
+       (_pkl_eq_struct): Likewise.
+       (_pkl_eq_any): Likewise.
+       * libpoke/pkl-gen.c (pkl_gen_ps_op_rela): Support EQ and NE for
+       `any' values.
+       (pkl_gen_pr_cast): Do nothing for casts to `any'.
+       * libpoke/pkl-typify.c (pkl_typify1_ps_op_rela): Likewise.
+       * libpoke/pkl-promo.c (pkl_promo_ps_op_rela): Likewise.
+       (promote_to_any): New function.
+       * testsuite/poke.pkl/eq-any-diag-1.pk: Remove test.
+       * testsuite/poke.pkl/neq-any-diag-1.pk: Likewise.
+       * testsuite/poke.pkl/ge-any-diag-1.pk: New test.
+       * testsuite/poke.pkl/le-any-diag-1.pk: Likewise.
+       * testsuite/poke.pkl/lt-any-diag-1.pk: Likewise.
+       * testsuite/poke.pkl/gt-any-diag-1.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-integral-1.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-integral-2.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-integral-3.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-integral-4.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-offset-1.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-offset-2.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-offset-3.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-offset-4.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-offset-5.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-offset-6.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-offset-7.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-offset-1.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-offset-2.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-offset-3.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-offset-4.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-offset-5.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-offset-6.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-offset-7.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-array-1.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-array-2.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-array-1.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-array-2.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-string-1.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-string-1.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-struct-1.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-struct-2.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-struct-3.pk: Likewise.
+       * testsuite/poke.pkl/eq-any-struct-4.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-struct-1.pk: Likewise.
+       * testsuite/poke.pkl/neq-any-struct-2.pk: Likewise.
+       * testsuite/Makefile.am (EXTRA_DIST): Update.
+
 2023-02-01  Mohammad-Reza Nabipoor  <mnabipoor@gnu.org>
 
        * poked/poked.c: Include `<unistd.h>' for `getuid'.
diff --git a/libpoke/pkl-gen.c b/libpoke/pkl-gen.c
index bbdfd7d2..46b12ca2 100644
--- a/libpoke/pkl-gen.c
+++ b/libpoke/pkl-gen.c
@@ -2443,6 +2443,8 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_pr_cast)
                     to_type);             /* IVAL(ULONG) IVAL */
       pkl_asm_insn (pasm, PKL_INSN_NIP);  /* IVAL */
     }
+  else if (PKL_AST_TYPE_CODE (to_type) == PKL_TYPE_ANY)
+    /* Do nothing in casts to `any'.  */;
   else
     assert (0);
 
@@ -4442,6 +4444,17 @@ PKL_PHASE_BEGIN_HANDLER (pkl_gen_ps_op_rela)
       pkl_asm_insn (pasm, rela_insn, op1_type);
       pkl_asm_insn (pasm, PKL_INSN_NIP2);
       break;
+    case PKL_TYPE_ANY:
+      assert (exp_code == PKL_AST_OP_EQ
+              || exp_code == PKL_AST_OP_NE);
+
+      pkl_asm_call (PKL_GEN_ASM, PKL_GEN_PAYLOAD->env, "_pkl_eq_any");
+      if (exp_code == PKL_AST_OP_NE)
+        {
+          pkl_asm_insn (pasm, PKL_INSN_NOT);
+          pkl_asm_insn (pasm, PKL_INSN_NIP);
+        }
+      break;
     default:
       assert (0);
       break;
diff --git a/libpoke/pkl-promo.c b/libpoke/pkl-promo.c
index 30030c44..daef078a 100644
--- a/libpoke/pkl-promo.c
+++ b/libpoke/pkl-promo.c
@@ -31,6 +31,21 @@
 /* Note the following macro evaluates the arguments twice!  */
 #define MAX(A,B) ((A) > (B) ? (A) : (B))
 
+/* Promote a given node A to an `any' type.  */
+
+static void
+promote_to_any (pkl_ast ast, pkl_ast_node *a, int *restart)
+{
+  pkl_ast_node any_type = pkl_ast_make_any_type (ast);
+  pkl_ast_loc loc = PKL_AST_LOC (*a);
+
+  *a = pkl_ast_make_cast (ast, any_type, ASTDEREF (*a));
+  PKL_AST_TYPE (*a) = ASTREF (any_type);
+  PKL_AST_LOC (*a) = loc;
+  *a = ASTREF (*a);
+  *restart = 1;
+}
+
 /* Promote a given node A to an integral type of width SIZE and sign
    SIGN, if possible.  Put the resulting node in A.  Return 1 if the
    promotion was successful, 0 otherwise.  */
@@ -593,6 +608,7 @@ PKL_PHASE_END_HANDLER
            ARRAY    x ARRAY    -> BOOL
            STRUCT   x STRUCT   -> BOOL
            FUNCTION x FUNCTION -> BOOL
+           ANY      x ANY      -> BOOL
 
    In the I x I -> I configuration, the types of the operands are
    promoted in a way both operands end having the same type, following
@@ -611,8 +627,24 @@ PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_rela)
   pkl_ast_node op2 = PKL_AST_EXP_OPERAND (exp, 1);
   pkl_ast_node op1_type = PKL_AST_TYPE (op1);
   pkl_ast_node op2_type = PKL_AST_TYPE (op2);
+  int op1_type_code = PKL_AST_TYPE_CODE (op1_type);
+  int op2_type_code = PKL_AST_TYPE_CODE (op2_type);
+
+  if (op1_type_code == PKL_TYPE_ANY || op2_type_code == PKL_TYPE_ANY)
+    {
+      int restart1, restart2;
+
+      /* Promote the non-any operand to `any'.  */
+      if (op1_type_code != PKL_TYPE_ANY)
+        promote_to_any (PKL_PASS_AST, &PKL_AST_EXP_OPERAND (exp, 0), 
&restart1);
+      if (op2_type_code != PKL_TYPE_ANY)
+        promote_to_any (PKL_PASS_AST, &PKL_AST_EXP_OPERAND (exp, 1), 
&restart2);
 
-  if (PKL_AST_TYPE_CODE (op1_type) != PKL_AST_TYPE_CODE (op2_type))
+      PKL_PASS_RESTART = restart1 || restart2;
+      PKL_PASS_DONE;
+    }
+
+  if (op1_type_code != op2_type_code)
     goto error;
 
   /* Handle integral struct operands.  */
@@ -682,8 +714,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_promo_ps_op_rela)
     case PKL_TYPE_ARRAY:
       /* Fallthrough.  */
     case PKL_TYPE_STRUCT:
-      /* Nothing to do.  */
-      break;
+      /* Fallthrough.  */
     case PKL_TYPE_FUNCTION:
       /* Nothing to do.  */
       break;
diff --git a/libpoke/pkl-rt.pk b/libpoke/pkl-rt.pk
index 3224b43d..2c5d23c6 100644
--- a/libpoke/pkl-rt.pk
+++ b/libpoke/pkl-rt.pk
@@ -954,6 +954,280 @@ immutable fun close = (int<32> ios) void:
   _pkl_run_ios_close_hook (ios);
 }
 
+/* Return whether the given value is integral, i.e. if it is
+   either a PVM int, uint, long or ulong.  */
+
+immutable fun _pkl_any_integral_p = (any v) int<32>:
+{
+  return (asm int<32>: ("typof; nip; tyisi; nip" : v)
+          || asm int<32>: ("typof; nip; tyisiu; nip" : v)
+          || asm int<32>: ("typof; nip; tyisl; nip" : v)
+          || asm int<32>: ("typof; nip; tyislu; nip" : v));
+}
+
+/* Multiply two uint<64> and return an array of two elements containing
+   the hi and lo part of the resulting uint<128> number.  This uses the
+   Hacker's Delight 32x32->64 algorithm.  */
+
+immutable fun _pkl_64x64_128 = (uint<64> a, uint<64> b) uint<64>[2]:
+{
+  var a1 = (a & 0xffff_ffff);
+  var b1 = (b & 0xffff_ffff);
+  var t = (a1 * b1);
+  var w3 = (t & 0xffff_ffff);
+  var k = (t .>> 32);
+
+  a .>>= 32;
+  t = (a * b1) + k;
+  k = (t & 0xffff_ffff);
+
+  var w1 = (t .>> 32);
+
+  b .>>= 32;
+  t = (a1 * b) + k;
+  k = (t .>> 32);
+
+  return [(a * b) + w1 + k, (t <<.32) + w3];
+}
+
+/* The following table is used by _pkl_eq_integral in order to
+   dispatch equality operations without using slow branches.
+
+   The array takes as indices the PVM type of the operands,
+   encoded the following way:
+
+   [op1type]       [op2type]
+       |               |
+       +- 0: int       +- 0: int
+       +- 1: uint      +- 1: uint
+       +- 2: long      +- 2: long
+       +- 3: ulong     +- 3: ulong  */
+
+immutable var _pkl_eq_integral_dispatch_table
+  = [
+      [
+        /* int, int */
+        lambda (any i1, any i2) int<32>:
+          {
+            return asm int<32>: ("eqi; nip2" : i1, i2);
+          },
+        /* int, uint */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i1u32 = asm uint<32>: ("itoiu 32; nip" : i1);
+            return asm int<32>: ("eqiu; nip2" : i1u32, i2);
+          },
+        /* int, long */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i1i64 = asm int<64>: ("itol 64; nip" : i1);
+            return asm int<32>: ("eql; nip2" : i1i64, i2);
+          },
+        /* int, ulong */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i1u64 = asm uint<64>: ("itolu 64; nip" : i1);
+            return asm int<32>: ("eqlu; nip2" : i1u64, i2);
+          },
+      ],
+      [
+        /* uint, int */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i2u32 = asm uint<32>: ("itoiu 32; nip" : i2);
+            return asm int<32>: ("eqiu; nip2" : i1, i2u32);
+          },
+        /* uint, uint */
+        lambda (any i1, any i2) int<32>:
+          {
+            return asm int<32>: ("eqiu; nip2" : i1, i2);
+          },
+        /* uint, long */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i1i64 = asm int<64>: ("iutol 64; nip" : i1);
+            return asm int<32>: ("eql; nip2" : i1i64, i2);
+          },
+        /* uint, ulong */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i1u64 = asm uint<64>: ("iutolu 64; nip" : i1);
+            return asm int<32>: ("eqlu; nip2" : i1u64, i2);
+          },
+      ],
+      [
+        /* long, int */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i2l64 = asm int<64>: ("itol 64; nip" : i2);
+            return asm int<32>: ("eql; nip2" : i1, i2l64);
+          },
+        /* long, uint */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i2l64 = asm int<64>: ("iutol 64; nip" : i2);
+            return asm int<32>: ("eql; nip2" : i1, i2l64);
+          },
+        /* long, long */
+        lambda (any i1, any i2) int<32>:
+          {
+            return asm int<32>: ("eql; nip2" : i1, i2);
+          },
+        /* long, ulong */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i1u64 = asm uint<64>: ("ltolu 64; nip" : i1);
+            return asm int<32>: ("eqlu; nip2" : i1u64, i2);
+          },
+      ],
+      [
+        /* ulong, int */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i2lu64 = asm uint<64>: ("itolu 64; nip" : i2);
+            return asm int<32>: ("eqlu; nip2" : i1, i2lu64);
+          },
+        /* ulong, uint */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i2lu64 = asm uint<64>: ("iutolu 64; nip" : i2);
+            return asm int<32>: ("eqlu; nip2" : i1, i2lu64);
+          },
+        /* ulong, long */
+        lambda (any i1, any i2) int<32>:
+          {
+            var i2lu64 = asm uint<64>: ("ltolu 64; nip" : i2);
+            return asm int<32>: ("eqlu; nip2" : i1, i2lu64);
+          },
+        /* ulong, ulong */
+        lambda (any i1, any i2) int<32>:
+          {
+            return asm int<32>: ("eqlu; nip2" : i1, i2);
+          },
+      ],
+    ];
+
+/* Determine whether two given integral values are equal.  */
+
+immutable fun _pkl_eq_integral = (any i1, any i2) int<32>:
+{
+  var i1idx = (asm int<32>: ("typof; nip; tyisi; nip" : i1)
+               + asm int<32>: ("typof; nip; tyisiu; nip" : i1) * 2
+               + asm int<32>: ("typof; nip; tyisl; nip" : i1) * 3
+               + asm int<32>: ("typof; nip; tyislu; nip" : i1) * 4) - 1;
+  var i2idx = (asm int<32>: ("typof; nip; tyisi; nip" : i2)
+               + asm int<32>: ("typof; nip; tyisiu; nip" : i2) * 2
+               + asm int<32>: ("typof; nip; tyisl; nip" : i2) * 3
+               + asm int<32>: ("typof; nip; tyislu; nip" : i2) * 4) - 1;
+
+  return _pkl_eq_integral_dispatch_table[i1idx][i2idx](i1, i2);
+}
+
+/* Determine whether two offset values of arbitrary magnitude and
+   unit are equal.  */
+
+immutable fun _pkl_eq_offset = (any v1, any v2) int<32>:
+{
+  fun abs_to_u64 = (any v) uint<64>:
+  {
+    if (asm int<32>: ("typof; nip; tyisi; nip" : v))
+      {
+        var i64 = asm int<64>: ("itol 64; nip" : v);
+        return i64 < 0 ? -i64 : i64;
+      }
+    else if (asm int<32>: ("typof; nip; tyisiu; nip" : v))
+      return asm uint<64>: ("iutolu 64; nip" : v);
+    else if (asm int<32>: ("typof; nip; tyisl; nip" : v))
+      {
+        var i64 = asm int<64>: ("ltol 64; nip" : v);
+        return i64 < 0 ? -i64 : i64;
+      }
+    else if (asm int<32>: ("typof; nip; tyislu; nip" : v))
+      return asm uint<64>: ("lutolu 64; nip" : v);
+
+    /* Unreachable.  */
+    assert (0, "internal run-time error in _pkl_eq_any.eq_offset.abs_to_u64");
+  }
+
+  var v1_magnitude = asm any: ("ogetm; nip" : v1);
+  var v1_unit = asm uint<64>: ("ogetu; nip" : v1);
+  var v2_magnitude = asm any: ("ogetm; nip" : v2);
+  var v2_unit = asm uint<64>: ("ogetu; nip" : v2);
+
+  /* If the units of both offsets are equal, then we got it easy: just
+     compare the magnitudes.  */
+  if (v1_unit == v2_unit) return
+     _pkl_eq_integral (v1_magnitude, v2_magnitude);
+
+  /* Convert the absolute value of the magnitudes to uint<64>  */
+  var v1_magnitude_u64 = abs_to_u64 (v1_magnitude);
+  var v2_magnitude_u64 = abs_to_u64 (v2_magnitude);
+
+  /* Now normalize them to bits by multiplying them by their
+     respective units.  But we gotta do this in 128-bit arithmetic to
+     avoid a possible overflow.  */
+  var v1_normalized = v1_unit == 1
+                      ? [0UL, v1_magnitude_u64]
+                      : _pkl_64x64_128 (v1_magnitude_u64, v1_unit);
+  var v2_normalized = v2_unit == 1
+                      ? [0UL, v2_magnitude_u64]
+                      : _pkl_64x64_128 (v2_magnitude_u64, v2_unit);
+
+  /* Compare and be done.  */
+  return v1_normalized == v2_normalized;
+}
+
+/* Determine whether two given string values are equal.  */
+
+immutable fun _pkl_eq_string = (any v1, any v2) int<32>:
+{
+  return asm int<32>: ("eqs; nip2" : v1, v2);
+}
+
+/* Determine whether two given `any' values are equal.  */
+
+immutable fun _pkl_eq_any = (any v1, any v2) int<32>:
+{
+  fun handle_composite = int<32>:
+  {
+    /* First check the lenght.  */
+    var v1_len = asm uint<64>: ("sel; nip" : v1);
+    var v2_len = asm uint<64>: ("sel; nip" : v2);
+
+    if (v1_len != v2_len)
+      return 0;
+
+    /* Check the elements.  */
+    for (var i = 0UL; i < v1_len; ++i)
+      if (!_pkl_eq_any (v1'elem (i), v2'elem (i)))
+        return 0;
+
+    return 1;
+  }
+
+  if (_pkl_any_integral_p (v1) && _pkl_any_integral_p (v2))
+    /* Integrals.  */
+    return _pkl_eq_integral (v1, v2);
+  else if (asm int<32>: ("typof; nip; tyiso; nip" : v1)
+           && asm int<32>: ("typof; nip; tyiso; nip" : v2))
+    /* Offsets.  */
+    return _pkl_eq_offset (v1, v2);
+  else if (asm int<32>: ("typof; nip; tyiss; nip" : v1)
+           && asm int<32>: ("typof; nip; tyss; nip" : v2))
+    /* Strings.  */
+    return _pkl_eq_string (v1, v2);
+  else if (asm int<32>: ("typof; nip; tyisa; nip" : v1)
+           && asm int<32>: ("typof; nip; tyisa; nip" : v2))
+    /* Arrays.  */
+    return handle_composite;
+  else if (asm int<32>: ("typof; nip; tyissct; nip" : v1)
+           && asm int<32>: ("typof; nip; tyissct; nip" : v2))
+    /* Structs.  */
+    return handle_composite;
+  else
+    return 0;
+}
+
 /* Printer and formatter for values of type `any'.  */
 
 immutable type _Pkl_Print_Format_Ctx =
diff --git a/libpoke/pkl-typify.c b/libpoke/pkl-typify.c
index cd1e4cbc..c67ae8a3 100644
--- a/libpoke/pkl-typify.c
+++ b/libpoke/pkl-typify.c
@@ -164,8 +164,8 @@ PKL_PHASE_END_HANDLER
 
 /* The type of the relational operations EQ, NE, LT, GT, LE and GE is
    a boolean encoded as a 32-bit signed integer type.  Their operands
-   should be either both integral types, or strings, or offsets.  EQ
-   and NE also accept arrays.  */
+   should be either both integral types, or strings, or offsets, or of
+   type `any'.  EQ and NE also accept arrays and any.  */
 
 PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_op_rela)
 {
@@ -181,6 +181,12 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_op_rela)
 
   pkl_ast_node exp_type;
 
+  if ((op1_type_code == PKL_TYPE_ANY
+       || op2_type_code == PKL_TYPE_ANY)
+      && (exp_code == PKL_AST_OP_EQ || exp_code == PKL_AST_OP_NE))
+    /* The not-any operand will be promoted to `any' in promo.  */
+    goto operand_types_ok;
+
   switch (op1_type_code)
     {
     case PKL_TYPE_INTEGRAL:
@@ -271,6 +277,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_op_rela)
       goto invalid_first_operand;
     }
 
+ operand_types_ok:
   /* Set the type of the expression node.  */
   exp_type = pkl_ast_make_integral_type (PKL_PASS_AST, 32, 1);
   PKL_AST_TYPE (PKL_PASS_NODE) = ASTREF (exp_type);
@@ -279,7 +286,7 @@ PKL_PHASE_BEGIN_HANDLER (pkl_typify1_ps_op_rela)
  invalid_first_operand:
   INVALID_OPERAND (op1,
                    exp_code == PKL_AST_OP_EQ || exp_code == PKL_AST_OP_NE
-                   ? "expected integral, string, offset, array, struct or 
function"
+                   ? "expected integral, string, offset, array, struct, 
function or any"
                    : "expected integral, string or offset");
 
  invalid_second_operand:
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 1ba2f989..bd5f6325 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -1258,7 +1258,24 @@ EXTRA_DIST = \
   poke.pkl/div-offsets-diag-3.pk \
   poke.pkl/diva-int-1.pk \
   poke.pkl/diva-offset-diag-1.pk \
-  poke.pkl/eq-any-diag-1.pk \
+  poke.pkl/eq-any-array-1.pk \
+  poke.pkl/eq-any-array-2.pk \
+  poke.pkl/eq-any-integral-1.pk \
+  poke.pkl/eq-any-integral-2.pk \
+  poke.pkl/eq-any-integral-3.pk \
+  poke.pkl/eq-any-integral-4.pk \
+  poke.pkl/eq-any-offset-1.pk \
+  poke.pkl/eq-any-offset-2.pk \
+  poke.pkl/eq-any-offset-3.pk \
+  poke.pkl/eq-any-offset-4.pk \
+  poke.pkl/eq-any-offset-5.pk \
+  poke.pkl/eq-any-offset-6.pk \
+  poke.pkl/eq-any-offset-7.pk \
+  poke.pkl/eq-any-string-1.pk \
+  poke.pkl/eq-any-struct-1.pk \
+  poke.pkl/eq-any-struct-2.pk \
+  poke.pkl/eq-any-struct-3.pk \
+  poke.pkl/eq-any-struct-4.pk \
   poke.pkl/eq-arrays-1.pk \
   poke.pkl/eq-arrays-2.pk \
   poke.pkl/eq-arrays-3.pk \
@@ -1507,6 +1524,7 @@ EXTRA_DIST = \
   poke.pkl/funcall-vararg-6.pk \
   poke.pkl/funcall-vararg-diag-1.pk \
   poke.pkl/funcall-vararg-diag-2.pk \
+  poke.pkl/ge-any-diag-1.pk \
   poke.pkl/ge-arrays-diag-1.pk \
   poke.pkl/ge-functions-diag-1.pk \
   poke.pkl/ge-integers-1.pk \
@@ -1527,6 +1545,7 @@ EXTRA_DIST = \
   poke.pkl/getenv-1.pk \
   poke.pkl/getenv-2.pk \
   poke.pkl/gettime-1.pk \
+  poke.pkl/gt-any-diag-1.pk \
   poke.pkl/gt-arrays-diag-1.pk \
   poke.pkl/gt-functions-diag-1.pk \
   poke.pkl/gt-functions-diag-2.pk \
@@ -1720,6 +1739,7 @@ EXTRA_DIST = \
   poke.pkl/lambda-4.pk \
   poke.pkl/lambda-5.pk \
   poke.pkl/lambda-diag-1.pk \
+  poke.pkl/le-any-diag-1.pk \
   poke.pkl/le-arrays-diag-1.pk \
   poke.pkl/le-functions-diag-1.pk \
   poke.pkl/le-integers-1.pk \
@@ -1746,6 +1766,7 @@ EXTRA_DIST = \
   poke.pkl/loop-2.pk \
   poke.pkl/loop-3.pk \
   poke.pkl/loop-4.pk \
+  poke.pkl/lt-any-diag-1.pk \
   poke.pkl/lt-arrays-diag-1.pk \
   poke.pkl/lt-functions-diag-1.pk \
   poke.pkl/lt-integers-1.pk \
@@ -1846,7 +1867,18 @@ EXTRA_DIST = \
   poke.pkl/neg-integers-2.pk \
   poke.pkl/neg-int-struct-1.pk \
   poke.pkl/neg-offsets-1.pk \
-  poke.pkl/neq-any-diag-1.pk \
+  poke.pkl/neq-any-array-1.pk \
+  poke.pkl/neq-any-array-2.pk \
+  poke.pkl/neq-any-offset-1.pk \
+  poke.pkl/neq-any-offset-2.pk \
+  poke.pkl/neq-any-offset-3.pk \
+  poke.pkl/neq-any-offset-4.pk \
+  poke.pkl/neq-any-offset-5.pk \
+  poke.pkl/neq-any-offset-6.pk \
+  poke.pkl/neq-any-offset-7.pk \
+  poke.pkl/neq-any-string-1.pk \
+  poke.pkl/neq-any-struct-1.pk \
+  poke.pkl/neq-any-struct-2.pk \
   poke.pkl/neq-integers-1.pk \
   poke.pkl/neq-integers-2.pk \
   poke.pkl/neq-offsets-1.pk \
diff --git a/testsuite/poke.pkl/eq-any-array-1.pk 
b/testsuite/poke.pkl/eq-any-array-1.pk
new file mode 100644
index 00000000..5ec13163
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-array-1.pk
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command {eq_any (string[](), string[]())} } */
+/* { dg-output "1" } */
+
+/* { dg-command {eq_any ([1,2,3], [1,2,3])} } */
+/* { dg-output "\n1" } */
+
+/* { dg-command {eq_any ([1,2,3], [1,2,3,4])} } */
+/* { dg-output "\n0" } */
+
+/* { dg-command {eq_any ([1,2,3], [1,2,9])} } */
+/* { dg-output "\n0" } */
+
+/* { dg-command {eq_any ([1,2,3], "foo")} } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-array-2.pk 
b/testsuite/poke.pkl/eq-any-array-2.pk
new file mode 100644
index 00000000..42dbb4a1
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-array-2.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command {eq_any ([[1,2,3]], [[1,2,3]])} } */
+/* { dg-output "1" } */
+
+/* { dg-command {eq_any ([[[1,2,3]]], [[[1,2,3]]])} } */
+/* { dg-output "\n1" } */
+
+/* { dg-command {eq_any ([[[1,10,3]]], [[[1,2,3]]])} } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-diag-1.pk 
b/testsuite/poke.pkl/eq-any-diag-1.pk
deleted file mode 100644
index 388bbe03..00000000
--- a/testsuite/poke.pkl/eq-any-diag-1.pk
+++ /dev/null
@@ -1,6 +0,0 @@
-/* { dg-do compile } */
-
-fun equalstructs = (any a, any b) int:
-  {
-    return a == b; /* { dg-error "invalid operand.*\n.*" } */
-  }
diff --git a/testsuite/poke.pkl/eq-any-integral-1.pk 
b/testsuite/poke.pkl/eq-any-integral-1.pk
new file mode 100644
index 00000000..84048330
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-integral-1.pk
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+/* This test tests the any equality and unequality operators
+   in the following integral configurations:
+
+        int OP int
+        int OP uint
+        int OP long
+        int OP ulong  */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command { eq_any (2, 2) } } */
+/* { dg-output "1" } */
+/* { dg-command { eq_any (3, 2) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2, 2U) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (3, 2U) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2, 2L) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (3, 2L) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2, 2LU) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (3, 2LU) } } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-integral-2.pk 
b/testsuite/poke.pkl/eq-any-integral-2.pk
new file mode 100644
index 00000000..24025c57
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-integral-2.pk
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+/* This test tests the any equality and unequality operators
+   in the following integral configurations:
+
+        uint OP int
+        uint OP uint
+        uint OP long
+        uint OP ulong  */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command { eq_any (2U, 2) } } */
+/* { dg-output "1" } */
+/* { dg-command { eq_any (2U, 3) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2U, 2U) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (2U, 3U) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2U, 2L) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (2U, 3L) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2U, 2LU) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (2U, 3LU) } } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-integral-3.pk 
b/testsuite/poke.pkl/eq-any-integral-3.pk
new file mode 100644
index 00000000..d2144d35
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-integral-3.pk
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+/* This test tests the any equality and unequality operators
+   in the following integral configurations:
+
+        long OP int
+        long OP uint
+        long OP long
+        long OP ulong  */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command { eq_any (2L, 2) } } */
+/* { dg-output "1" } */
+/* { dg-command { eq_any (100L, 2) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2L, 2U) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (100L, 2U) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2L, 2L) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (100L, 2L) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2L, 2UL) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (100L, 2UL) } } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-integral-4.pk 
b/testsuite/poke.pkl/eq-any-integral-4.pk
new file mode 100644
index 00000000..42805865
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-integral-4.pk
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+
+/* This test tests the any equality and unequality operators
+   in the following integral configurations:
+
+        ulong OP int
+        ulong OP uint
+        ulong OP long
+        ulong OP ulong  */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command { eq_any (2LU, 2) } } */
+/* { dg-output "1" } */
+/* { dg-command { eq_any (2LU, 200) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2LU, 2U) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (2LU, 200U) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2LU, 2L) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (2LU, 200L) } } */
+/* { dg-output "\n0" } */
+
+/* { dg-command { eq_any (2LU, 2LU) } } */
+/* { dg-output "\n1" } */
+/* { dg-command { eq_any (2LU, 200LU) } } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-offset-1.pk 
b/testsuite/poke.pkl/eq-any-offset-1.pk
new file mode 100644
index 00000000..43037e5e
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-offset-1.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command { eq_any (2LU#MiB, 2048#KiB) } } */
+/* { dg-output "1" } */
diff --git a/testsuite/poke.pkl/eq-any-offset-2.pk 
b/testsuite/poke.pkl/eq-any-offset-2.pk
new file mode 100644
index 00000000..5018cad6
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-offset-2.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command { eq_any (2LU#MiB, 2049#KiB) } } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/eq-any-offset-3.pk 
b/testsuite/poke.pkl/eq-any-offset-3.pk
new file mode 100644
index 00000000..a0f81424
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-offset-3.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command { eq_any (2LU#MiB, 2048#3) } } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/eq-any-offset-4.pk 
b/testsuite/poke.pkl/eq-any-offset-4.pk
new file mode 100644
index 00000000..8403aa38
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-offset-4.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun eq_any = (any a) int<32>: { return a == 2048#KiB; }
+
+/* { dg-command { eq_any (2LU#MiB) } } */
+/* { dg-output "1" } */
diff --git a/testsuite/poke.pkl/eq-any-offset-5.pk 
b/testsuite/poke.pkl/eq-any-offset-5.pk
new file mode 100644
index 00000000..c92066d3
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-offset-5.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun eq_any = (any a) int<32>: { return 2048#KiB == a; }
+
+/* { dg-command { eq_any (2LU#MiB) } } */
+/* { dg-output "1" } */
diff --git a/testsuite/poke.pkl/eq-any-offset-6.pk 
b/testsuite/poke.pkl/eq-any-offset-6.pk
new file mode 100644
index 00000000..22d37c6e
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-offset-6.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun eq_any = (any a) int<32>: { return 2047#KiB == a; }
+
+/* { dg-command { eq_any (2LU#MiB) } } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/eq-any-offset-7.pk 
b/testsuite/poke.pkl/eq-any-offset-7.pk
new file mode 100644
index 00000000..f5c2cdd8
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-offset-7.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun eq_any = (any a) int<32>: { return a == 2047#KiB; }
+
+/* { dg-command { eq_any (2LU#MiB) } } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/eq-any-string-1.pk 
b/testsuite/poke.pkl/eq-any-string-1.pk
new file mode 100644
index 00000000..1a77b669
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-string-1.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+/* { dg-command {eq_any ("","")} } */
+/* { dg-output "1" } */
+
+/* { dg-command {eq_any ("foo", "foo")} } */
+/* { dg-output "\n1" } */
+
+/* { dg-command {eq_any ("foo", "bar") } } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-struct-1.pk 
b/testsuite/poke.pkl/eq-any-struct-1.pk
new file mode 100644
index 00000000..e9a68f62
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-struct-1.pk
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+type Foo =
+  struct
+  {
+  };
+
+/* { dg-command {eq_any ( Foo {} , Foo {} )} } */
+/* { dg-output "1" } */
diff --git a/testsuite/poke.pkl/eq-any-struct-2.pk 
b/testsuite/poke.pkl/eq-any-struct-2.pk
new file mode 100644
index 00000000..27d2ccf0
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-struct-2.pk
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+type Foo =
+  struct
+  {
+    int i;
+    long l;
+  };
+
+/* { dg-command {eq_any ( Foo {} , Foo {} )} } */
+/* { dg-output "1" } */
+
+/* { dg-command {eq_any ( Foo { i = 2 } , Foo { i = 2} )} } */
+/* { dg-output "\n1" } */
+
+/* { dg-command {eq_any ( Foo { i = 2 } , Foo { i = 2, l = 3} )} } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-struct-3.pk 
b/testsuite/poke.pkl/eq-any-struct-3.pk
new file mode 100644
index 00000000..4bc82a2c
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-struct-3.pk
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+type Foo =
+  struct
+  {
+    int i;
+    long l;
+    string s if i != 0;
+  };
+
+/* { dg-command {eq_any ( Foo {} , Foo {} )} } */
+/* { dg-output "1" } */
+
+/* { dg-command {eq_any ( Foo { i = 2, s = "foo" } , Foo { i = 2, s = "foo"} 
)} } */
+/* { dg-output "\n1" } */
+
+/* { dg-command {eq_any ( Foo { i = 0 } , Foo { i = 2, l = 3, s = "bar"} )} } 
*/
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/eq-any-struct-4.pk 
b/testsuite/poke.pkl/eq-any-struct-4.pk
new file mode 100644
index 00000000..aa168f73
--- /dev/null
+++ b/testsuite/poke.pkl/eq-any-struct-4.pk
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40  0x50 0x60 0x70 0x80   0x90 0xa0 0xb0 
0xc0} } */
+
+fun eq_any = (any a, any b) int<32>: { return a == b; }
+
+type Foo =
+  struct
+  {
+    struct
+    {
+      int i;
+    } s;
+    long l;
+  };
+
+/* { dg-command {eq_any ( Foo {} , Foo {} )} } */
+/* { dg-output "1" } */
+
+/* { dg-command {var f = Foo @ 0#B} } */
+/* { dg-command {eq_any ( f , Foo {} )} } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/ge-any-diag-1.pk 
b/testsuite/poke.pkl/ge-any-diag-1.pk
new file mode 100644
index 00000000..695a59fc
--- /dev/null
+++ b/testsuite/poke.pkl/ge-any-diag-1.pk
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+
+fun ge_any = (any a, any b) int<32>:
+{
+  return a >= b; /* { dg-error "invalid operand.*\n.*got any" } */
+}
diff --git a/testsuite/poke.pkl/gt-any-diag-1.pk 
b/testsuite/poke.pkl/gt-any-diag-1.pk
new file mode 100644
index 00000000..fcaeef9c
--- /dev/null
+++ b/testsuite/poke.pkl/gt-any-diag-1.pk
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+
+fun gt_any = (any a, any b) int<32>:
+{
+  return a > b; /* { dg-error "invalid operand.*\n.*got any" } */
+}
diff --git a/testsuite/poke.pkl/le-any-diag-1.pk 
b/testsuite/poke.pkl/le-any-diag-1.pk
new file mode 100644
index 00000000..60e16e0e
--- /dev/null
+++ b/testsuite/poke.pkl/le-any-diag-1.pk
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+
+fun le_any = (any a, any b) int<32>:
+{
+  return a <= b; /* { dg-error "invalid operand.*\n.*got any" } */
+}
diff --git a/testsuite/poke.pkl/lt-any-diag-1.pk 
b/testsuite/poke.pkl/lt-any-diag-1.pk
new file mode 100644
index 00000000..d4164b0a
--- /dev/null
+++ b/testsuite/poke.pkl/lt-any-diag-1.pk
@@ -0,0 +1,6 @@
+/* { dg-do compile } */
+
+fun lt_any = (any a, any b) int<32>:
+{
+  return a < b; /* { dg-error "invalid operand.*\n.*got any" } */
+}
diff --git a/testsuite/poke.pkl/neq-any-array-1.pk 
b/testsuite/poke.pkl/neq-any-array-1.pk
new file mode 100644
index 00000000..b3688382
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-array-1.pk
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+
+fun neq_any = (any a, any b) int<32>: { return a != b; }
+
+/* { dg-command {neq_any ([1,2,3], [1,2,3])} } */
+/* { dg-output "0" } */
+
+/* { dg-command {neq_any ([1,2,3], [1,2,3,4])} } */
+/* { dg-output "\n1" } */
+
+/* { dg-command {neq_any ([1,2,3], [1,2,9])} } */
+/* { dg-output "\n1" } */
+
+/* { dg-command {neq_any ([1,2,3], "foo")} } */
+/* { dg-output "\n1" } */
diff --git a/testsuite/poke.pkl/neq-any-array-2.pk 
b/testsuite/poke.pkl/neq-any-array-2.pk
new file mode 100644
index 00000000..999fb7d9
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-array-2.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+fun neq_any = (any a, any b) int<32>: { return a != b; }
+
+/* { dg-command {neq_any ([[1,2,3]], [[1,2,3]])} } */
+/* { dg-output "0" } */
+
+/* { dg-command {neq_any ([[[1,2,3]]], [[[1,2,3]]])} } */
+/* { dg-output "\n0" } */
+
+/* { dg-command {neq_any ([[[1,10,3]]], [[[1,2,3]]])} } */
+/* { dg-output "\n1" } */
diff --git a/testsuite/poke.pkl/neq-any-diag-1.pk 
b/testsuite/poke.pkl/neq-any-diag-1.pk
deleted file mode 100644
index 8451aebe..00000000
--- a/testsuite/poke.pkl/neq-any-diag-1.pk
+++ /dev/null
@@ -1,6 +0,0 @@
-/* { dg-do compile } */
-
-fun equalstructs = (any a, any b) int:
-  {
-    return a != b; /* { dg-error "invalid operand.*\n.*" } */
-  }
diff --git a/testsuite/poke.pkl/neq-any-offset-1.pk 
b/testsuite/poke.pkl/neq-any-offset-1.pk
new file mode 100644
index 00000000..59d430d6
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-offset-1.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun neq_any = (any a, any b) int<32>: { return a != b; }
+
+/* { dg-command { neq_any (2LU#MiB, 2048#KiB) } } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/neq-any-offset-2.pk 
b/testsuite/poke.pkl/neq-any-offset-2.pk
new file mode 100644
index 00000000..e9f97e3d
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-offset-2.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun neq_any = (any a, any b) int<32>: { return a != b; }
+
+/* { dg-command { neq_any (2LU#MiB, 2049#KiB) } } */
+/* { dg-output "1" } */
diff --git a/testsuite/poke.pkl/neq-any-offset-3.pk 
b/testsuite/poke.pkl/neq-any-offset-3.pk
new file mode 100644
index 00000000..bee9b453
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-offset-3.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun neq_any = (any a, any b) int<32>: { return a != b; }
+
+/* { dg-command { neq_any (2LU#MiB, 2048#3) } } */
+/* { dg-output "1" } */
diff --git a/testsuite/poke.pkl/neq-any-offset-4.pk 
b/testsuite/poke.pkl/neq-any-offset-4.pk
new file mode 100644
index 00000000..bf4ea3f2
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-offset-4.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun neq_any = (any a) int<32>: { return a != 2048#KiB; }
+
+/* { dg-command { neq_any (2LU#MiB) } } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/neq-any-offset-5.pk 
b/testsuite/poke.pkl/neq-any-offset-5.pk
new file mode 100644
index 00000000..f84c71ca
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-offset-5.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun neq_any = (any a) int<32>: { return 2048#KiB != a; }
+
+/* { dg-command { neq_any (2LU#MiB) } } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/neq-any-offset-6.pk 
b/testsuite/poke.pkl/neq-any-offset-6.pk
new file mode 100644
index 00000000..6dad54df
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-offset-6.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun neq_any = (any a) int<32>: { return 2047#KiB != a; }
+
+/* { dg-command { neq_any (2LU#MiB) } } */
+/* { dg-output "1" } */
diff --git a/testsuite/poke.pkl/neq-any-offset-7.pk 
b/testsuite/poke.pkl/neq-any-offset-7.pk
new file mode 100644
index 00000000..ebd07539
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-offset-7.pk
@@ -0,0 +1,6 @@
+/* { dg-do run } */
+
+fun neq_any = (any a) int<32>: { return a != 2047#KiB; }
+
+/* { dg-command { neq_any (2LU#MiB) } } */
+/* { dg-output "1" } */
diff --git a/testsuite/poke.pkl/neq-any-string-1.pk 
b/testsuite/poke.pkl/neq-any-string-1.pk
new file mode 100644
index 00000000..c10b6dfc
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-string-1.pk
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+
+fun neq_any = (any a, any b) int<32>: { return a != b; }
+
+/* { dg-command {neq_any ("","")} } */
+/* { dg-output "0" } */
+
+/* { dg-command {neq_any ("foo", "foo")} } */
+/* { dg-output "\n0" } */
+
+/* { dg-command {neq_any ("foo", "bar") } } */
+/* { dg-output "\n1" } */
diff --git a/testsuite/poke.pkl/neq-any-struct-1.pk 
b/testsuite/poke.pkl/neq-any-struct-1.pk
new file mode 100644
index 00000000..8f920468
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-struct-1.pk
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+
+fun neq_any = (any a, any b) int<32>: { return a != b; }
+
+type Foo =
+  struct
+  {
+  };
+
+/* { dg-command {neq_any ( Foo {} , Foo {} )} } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/neq-any-struct-2.pk 
b/testsuite/poke.pkl/neq-any-struct-2.pk
new file mode 100644
index 00000000..47f72f2b
--- /dev/null
+++ b/testsuite/poke.pkl/neq-any-struct-2.pk
@@ -0,0 +1,19 @@
+/* { dg-do run } */
+
+fun neq_any = (any a, any b) int<32>: { return a != b; }
+
+type Foo =
+  struct
+  {
+    int i;
+    long l;
+  };
+
+/* { dg-command {neq_any ( Foo {} , Foo {} )} } */
+/* { dg-output "0" } */
+
+/* { dg-command {neq_any ( Foo { i = 2 } , Foo { i = 2} )} } */
+/* { dg-output "\n0" } */
+
+/* { dg-command {neq_any ( Foo { i = 2 } , Foo { i = 2, l = 3} )} } */
+/* { dg-output "\n1" } */
-- 
2.30.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]