This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/79079] New: [6/7] Wrong code gen for __builtin_mul_overflow when TRULY_NOOP_TRUNCATION (32, 64) == false


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79079

            Bug ID: 79079
           Summary: [6/7] Wrong code gen for __builtin_mul_overflow when
                    TRULY_NOOP_TRUNCATION (32, 64) == false
           Product: gcc
           Version: 6.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: target
          Assignee: unassigned at gcc dot gnu.org
          Reporter: npickito at gmail dot com
  Target Milestone: ---
            Target: mips64-unknown-linux, riscv64-elf, riscv64-linux

expand function on __builtin_mul_overflow is missing gen a truncdisi2 after
muldi3 since it's just call gen_lowpart and it's not consider
TRULY_NOOP_TRUNCATION == false

GCC configure:
--target=mips64-unknown-linux-gnu --with-abi=64
or
--target=riscv64-unknown-linux-gnu (Review in progress)
(https://gcc.gnu.org/ml/gcc-patches/2017-01/msg00776.html)


Testcase:
c-c++-common/torture/builtin-arith-overflow-12.c

Reduced testcase (extract from builtin-arith-overflow-12.c):
int v;
__attribute__((noinline, noclone)) void
bar (void)
{
  v++;
}

__attribute__((noinline, noclone)) signed int t115_1mul (unsigned int x, signed
int y) {
  signed int r;
  if (__builtin_mul_overflow (x, y, &r))
    bar ();
  return r;
}

int main()
{
  unsigned int x = ((unsigned int) 0x7fffffff + 1);
  signed int y = (-1);
  signed int r1, r2; v = 0;
  if (t115_1mul (x, y) != (signed int) ((-0x7fffffff - 1)))
     __builtin_abort ();

  return 0;
}



Patch:
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index c07b538..3c92183 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -1272,7 +1272,7 @@ expand_mul_overflow (location_t loc, tree lhs, tree arg0,
tree arg1,
          rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
                                     NULL_RTX, uns);
          hipart = gen_lowpart (mode, hipart);
-         res = gen_lowpart (mode, res);
+         res = convert_modes (mode, wmode, res, uns);
          if (uns)
            /* For the unsigned multiplication, there was overflow if
               HIPART is non-zero.  */

This patch already run gcc testsuite for mips64, x86-64 and riscv64/riscv32,
fix  mips64 and riscv64 for builtin-arith-overflow-12.c and no introduce new
regression on x86-64 and riscv32

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]