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