Blob Blame History Raw
commit 124ae6cfa303f0cc71ffd685620cb57c4f8f02bb
Author: Andreas Arnez <arnez@linux.ibm.com>
Date:   Mon Jun 7 14:01:53 2021 +0200

    s390x: Don't emit "vector or with complement" on z13
    
    The z/Architecture instruction "vector or with complement" (VOC) can be
    used as an optimization to combine "vector or" with "vector nor".  This is
    exploited in Valgrind since commit 6c1cb1a0128b00858b973e.  However, VOC
    requires the vector-enhancements facility 1, which is not installed on a
    z13 CPU.  Thus Valgrind can now run into SIGILL on z13 when trying to
    execute vector string instructions.
    
    Fix this by suppressing the VOC optimization unless the
    vector-enhancements facility 1 is recognized on the host.

diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c
index ee20c6711..15ca92a6b 100644
--- a/VEX/priv/host_s390_isel.c
+++ b/VEX/priv/host_s390_isel.c
@@ -4102,14 +4102,17 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr)
       case Iop_OrV128:
          size = 16;
          vec_binop = S390_VEC_OR;
-         if (arg1->tag == Iex_Unop && arg1->Iex.Unop.op == Iop_NotV128) {
-            IRExpr* orig_arg1 = arg1;
-            arg1 = arg2;
-            arg2 = orig_arg1->Iex.Unop.arg;
-            vec_binop = S390_VEC_ORC;
-         } else if (arg2->tag == Iex_Unop && arg2->Iex.Unop.op == Iop_NotV128) {
-            arg2 = arg2->Iex.Unop.arg;
-            vec_binop = S390_VEC_ORC;
+         if (s390_host_has_vxe) {
+            if (arg1->tag == Iex_Unop && arg1->Iex.Unop.op == Iop_NotV128) {
+               IRExpr* orig_arg1 = arg1;
+               arg1 = arg2;
+               arg2 = orig_arg1->Iex.Unop.arg;
+               vec_binop = S390_VEC_ORC;
+            } else if (arg2->tag == Iex_Unop &&
+                       arg2->Iex.Unop.op == Iop_NotV128) {
+               arg2 = arg2->Iex.Unop.arg;
+               vec_binop = S390_VEC_ORC;
+            }
          }
          goto Iop_VV_wrk;