From: Florian Krohm Date: Tue, 14 Apr 2026 21:36:18 +0000 (+0000) Subject: s390: Bug fix in insn selection X-Git-Tag: VALGRIND_3_27_0~10 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=a16e818e63ff41abba7c17aa5fd75f120e9700df;p=thirdparty%2Fvalgrind.git s390: Bug fix in insn selection The bug was introduced in b3830b82f4 and exposed by GCC when compiling with -g (without -O2). Here's the thing: if (expr->Iex.Binop.op == Iop_Add64) { ---> ULong disp = arg2->Iex.Const.con->Ico.U64; if (arg2->tag == Iex_Const && ulong_fits_signed_20bit(disp)) { h1 = s390_isel_int_expr(env, arg1); This possibly segfaults when arg2 is not a constant. Optimising GCC figures it can first check arg2->tag == Iex_Const which is cheaper than disp = arg2->Iex.Const.con->Ico.U64; Nice one. Regtested with both default compiler flags and -g only. --- diff --git a/VEX/priv/host_s390_isel.c b/VEX/priv/host_s390_isel.c index cf54dd48a..abf026eb1 100644 --- a/VEX/priv/host_s390_isel.c +++ b/VEX/priv/host_s390_isel.c @@ -1714,9 +1714,9 @@ s390_isel_int_expr_wrk(ISelEnv *env, IRExpr *expr) } /* Is this a match for "load address"? */ - if (expr->Iex.Binop.op == Iop_Add64) { + if (expr->Iex.Binop.op == Iop_Add64 && arg2->tag == Iex_Const) { ULong disp = arg2->Iex.Const.con->Ico.U64; - if (arg2->tag == Iex_Const && ulong_fits_signed_20bit(disp)) { + if (ulong_fits_signed_20bit(disp)) { h1 = s390_isel_int_expr(env, arg1); opnd.tag = S390_OPND_AMODE; if (ulong_fits_unsigned_12bit(disp)) {