From a16e818e63ff41abba7c17aa5fd75f120e9700df Mon Sep 17 00:00:00 2001 From: Florian Krohm Date: Tue, 14 Apr 2026 21:36:18 +0000 Subject: [PATCH] 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. --- VEX/priv/host_s390_isel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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)) { -- 2.47.3