From 842125faf89af8425906ff329d4e16a9cae76f0d Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 1 Apr 2020 13:45:22 +0900 Subject: [PATCH] [qfcc] Add a failing test for aliased live vars I'm not sure if it's due more to doubles or unions, but the bug was found via double. It seems the dags code generator doesn't see that the assignment to the union's double field kills the two int fields. The test passes when NOT optimizing. --- tools/qfcc/test/Makefile.am | 10 +++++++++ tools/qfcc/test/double-alias.r | 41 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 tools/qfcc/test/double-alias.r diff --git a/tools/qfcc/test/Makefile.am b/tools/qfcc/test/Makefile.am index a7b10901f..2b454b7a5 100644 --- a/tools/qfcc/test/Makefile.am +++ b/tools/qfcc/test/Makefile.am @@ -43,6 +43,7 @@ test_progs_dat=\ compound.dat \ deadbool.dat \ double.dat \ + double-alias.dat \ enum.dat \ fordecl.dat \ func-expr.dat \ @@ -209,6 +210,15 @@ double.run: Makefile build-run include ./$(DEPDIR)/double.Qo # am--include-marker r_depfiles_remade += ./$(DEPDIR)/double.Qo +double_alias_dat_SOURCES=double-alias.r +double_alias_obj=$(double_alias_dat_SOURCES:.r=.qfo) +double-alias.dat$(EXEEXT): $(double_alias_obj) $(QFCC_DEP) + $(QFCC) $(QCFLAGS) -o $@ $(double_alias_obj) +double-alias.run: Makefile build-run + @$(srcdir)/build-run $@ +include ./$(DEPDIR)/double-alias.Qo # am--include-marker +r_depfiles_remade += ./$(DEPDIR)/double-alias.Qo + classarray.run$(EXEEXT): classarray.r Makefile build-compile-fail-run @$(srcdir)/build-compile-fail-run $@ $(QFCC) $(QCFLAGS) $< diff --git a/tools/qfcc/test/double-alias.r b/tools/qfcc/test/double-alias.r new file mode 100644 index 000000000..6050d2f6d --- /dev/null +++ b/tools/qfcc/test/double-alias.r @@ -0,0 +1,41 @@ +void printf (string fmt, ...) = #0; +# define M_PI 3.14159265358979323846 + +union { + double d; + int i[2]; +} type_pun; + +int alias_printf (string fmt, ...); + +int +test_alias () +{ + int fail = 0; + type_pun.d = M_PI; + fail = alias_printf ("%g %08x%08x\n", type_pun.d, + type_pun.i[1], type_pun.i[0]); + return fail; +} + +int +alias_printf (string fmt, ...) +{ + int fail = 0; + // this will fail on big-endian systems + fail = (@args.list[2].integer_val != 0x54442d18 + || @args.list[1].integer_val != 0x400921fb); + printf ("%g %08x%08x\n", + @args.list[0].integer_val, + @args.list[2].integer_val, + @args.list[1].integer_val); + return fail; +} + +int +main () +{ + int fail = 0; + fail |= test_alias (); + return fail; +}