|
|
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 |
|