aa9a38
commit 124ae6cfa303f0cc71ffd685620cb57c4f8f02bb
aa9a38
Author: Andreas Arnez <arnez@linux.ibm.com>
aa9a38
Date:   Mon Jun 7 14:01:53 2021 +0200
aa9a38
aa9a38
    s390x: Don't emit "vector or with complement" on z13
aa9a38
    
aa9a38
    The z/Architecture instruction "vector or with complement" (VOC) can be
aa9a38
    used as an optimization to combine "vector or" with "vector nor".  This is
aa9a38
    exploited in Valgrind since commit 6c1cb1a0128b00858b973e.  However, VOC
aa9a38
    requires the vector-enhancements facility 1, which is not installed on a
aa9a38
    z13 CPU.  Thus Valgrind can now run into SIGILL on z13 when trying to
aa9a38
    execute vector string instructions.
aa9a38
    
aa9a38
    Fix this by suppressing the VOC optimization unless the
aa9a38
    vector-enhancements facility 1 is recognized on the host.
aa9a38
aa9a38
diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c
aa9a38
index ee20c6711..15ca92a6b 100644
aa9a38
--- a/VEX/priv/host_s390_isel.c
aa9a38
+++ b/VEX/priv/host_s390_isel.c
aa9a38
@@ -4102,14 +4102,17 @@ s390_isel_vec_expr_wrk(ISelEnv *env, IRExpr *expr)
aa9a38
       case Iop_OrV128:
aa9a38
          size = 16;
aa9a38
          vec_binop = S390_VEC_OR;
aa9a38
-         if (arg1->tag == Iex_Unop && arg1->Iex.Unop.op == Iop_NotV128) {
aa9a38
-            IRExpr* orig_arg1 = arg1;
aa9a38
-            arg1 = arg2;
aa9a38
-            arg2 = orig_arg1->Iex.Unop.arg;
aa9a38
-            vec_binop = S390_VEC_ORC;
aa9a38
-         } else if (arg2->tag == Iex_Unop && arg2->Iex.Unop.op == Iop_NotV128) {
aa9a38
-            arg2 = arg2->Iex.Unop.arg;
aa9a38
-            vec_binop = S390_VEC_ORC;
aa9a38
+         if (s390_host_has_vxe) {
aa9a38
+            if (arg1->tag == Iex_Unop && arg1->Iex.Unop.op == Iop_NotV128) {
aa9a38
+               IRExpr* orig_arg1 = arg1;
aa9a38
+               arg1 = arg2;
aa9a38
+               arg2 = orig_arg1->Iex.Unop.arg;
aa9a38
+               vec_binop = S390_VEC_ORC;
aa9a38
+            } else if (arg2->tag == Iex_Unop &&
aa9a38
+                       arg2->Iex.Unop.op == Iop_NotV128) {
aa9a38
+               arg2 = arg2->Iex.Unop.arg;
aa9a38
+               vec_binop = S390_VEC_ORC;
aa9a38
+            }
aa9a38
          }
aa9a38
          goto Iop_VV_wrk;
aa9a38