From: Julian Seward Date: Tue, 12 Dec 2017 21:31:54 +0000 (+0100) Subject: Fix false positive with s390x cgijnl instruction testing against sign bit. X-Git-Tag: VALGRIND_3_14_0~189 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d6a810760ec61ddedf15445457edbbe288536a2f;p=thirdparty%2Fvalgrind.git Fix false positive with s390x cgijnl instruction testing against sign bit. https://bugs.kde.org/show_bug.cgi?id=387712 When the cgij "compare immediate and branch relative" instruction compares 0 <=signed dep1, that means dep1 >=signed 0, so it is a test against the most significant bit of dep1. So only that bit needs to be defined. --- diff --git a/NEWS b/NEWS index bb3d6c2a8e..de4f6687ea 100644 --- a/NEWS +++ b/NEWS @@ -77,6 +77,7 @@ where XXXXXX is the bug number as listed below. 385912 none/tests/rlimit_nofile fails on newer glibc/kernel. 385939 Optionally exit on the first error 386397 PPC64, valgrind truncates powerpc timebase to 32-bits. +387712 s390x cgijnl reports Conditional jump depends on uninitialised value n-i-bz Fix missing workq_ops operations (macOS) n-i-bz fix bug in strspn replacement diff --git a/VEX/priv/guest_s390_helpers.c b/VEX/priv/guest_s390_helpers.c index 4cccdec79f..aacd833b54 100644 --- a/VEX/priv/guest_s390_helpers.c +++ b/VEX/priv/guest_s390_helpers.c @@ -1818,6 +1818,13 @@ isC64(const IRExpr *expr) return expr->tag == Iex_Const && expr->Iex.Const.con->tag == Ico_U64; } +static inline Bool +isC64_exactly(const IRExpr *expr, ULong n) +{ + return expr->tag == Iex_Const && expr->Iex.Const.con->tag == Ico_U64 + && expr->Iex.Const.con->Ico.U64 == n; +} + /* The returned expression is NULL if no specialization was found. In that case the helper function will be called. Otherwise, the expression has @@ -1895,9 +1902,25 @@ guest_s390x_spechelper(const HChar *function_name, IRExpr **args, } /* cc_dep1 > cc_dep2 ----> cc_dep2 < cc_dep1 */ if (cond == 2 || cond == 2 + 1) { + /* If we ever need the counterpart of the bug387712 fix just + below, then here is the place. We'll need to give an + alternative expression for the case "cc_dep2 dep1 >=signed 0 + --> m.s.bit of dep1 == 0 */ + /* See bug 387712. This is an old trick from gcc to extract + the most significant bit of a word. */ + return unop(Iop_64to32, + binop(Iop_Xor64, + binop(Iop_Shr64, cc_dep1, mkU8(63)), + mkU64(1))); + } return unop(Iop_1Uto32, binop(Iop_CmpLE64S, cc_dep2, cc_dep1)); } if (cond == 8 + 4 + 2 || cond == 8 + 4 + 2 + 1) {