]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
s390: Bug fix in insn selection master
authorFlorian Krohm <flo2030@eich-krohm.de>
Tue, 14 Apr 2026 21:36:18 +0000 (21:36 +0000)
committerFlorian Krohm <flo2030@eich-krohm.de>
Tue, 14 Apr 2026 21:36:18 +0000 (21:36 +0000)
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

index cf54dd48a8707ce15ddbaa3f63b6c66f01a84d35..abf026eb168d0b15dd24c7f60b84780971e3806b 100644 (file)
@@ -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)) {