History

Adjust return value promotion for some archs

this is a bit complicated: for i386 and x86-64 we really need to extend return values ourself, as the common code now does. For arm64 this at least preserves old behaviour. For riscv64 we don't have to extend ourself but can expect things to be extended up to int (this matters for var-args tests, when the sign-extension to int64 needs to happen explicitely). As the extensions are useless, don't do them. And for arm32 we actually can't express GCC behaviour: the callee side expects the return value to be correctly extended to int32, but remembers the original type. In case the ultimate target type for the call result is only int, no further extension is done. But in case the target type is e.g. int64 an extension happens, but not from int32 but from the original type. We don't know the ultimate target type, so we have to choose a type to put into vtop: * original type (plus VT_MUSTCAST) - this looses when the ultimate target is int (GCC: no cast, TCC: a cast) * int (without MUSTCAST) - this looses when the ultimate target is int64 (GCC: cast from original type, TCC: cast from int) This difference can only be seen with undefined sources, like the testcases, so it doesn't seem worthwhile to try an make it work, just disable the test on arm and choose the second variant as that generates less code.

Michael Matz committed 6 years ago

Commit c8ca64d1 parent 2d17e5a5 files · +26 −10Browse files

Showing the changes to tests (1 of 5 files). Show all

Unified · Split

tests/tcctest.c+6−8
@@ -1210,13 +1210,7 @@ void struct_test() · 1209 unmodified lines
12101210 /* simulate char/short return value with undefined upper bits */
12111211 static int __csf(int x) { return x; }
12121212 static void *_csf = __csf;
1213−#ifdef __TINYC__
12141213 #define csf(t,n) ((t(*)(int))_csf)(n)
1215−#define csfb csf
1216−#else /* arm gcc maybe doesn't promote function return values */
1217−#define csf(t,n) (t) n
1218−#define csfb(t,n) (t) (n & 255)
1219−#endif
12201214
12211215 /* XXX: depend on endianness */
12221216 void char_short_test()
@@ -1257,14 +1251,18 @@ void char_short_test() · 34 unmodified lines
12571251 var4 = 0x11223344aa998877ULL;
12581252 printf("promote char/short assign VA %d %d\n", var3 = var1 + 1, var3 = var4 + 1);
12591253 printf("promote char/short cast VA %d %d\n", (char)(var1 + 1), (char)(var4 + 1));
1254+#if !defined(__arm__)
1255+ /* We can't really express GCC behaviour of return type promotion in
1256+ the presence of undefined behaviour (like __csf is). */
12601257 var1 = csf(unsigned char,0x89898989);
12611258 var4 = csf(signed char,0xabababab);
12621259 printf("promote char/short funcret %d "LONG_LONG_FORMAT"\n", var1, var4);
12631260 printf("promote char/short fumcret VA %d %d %d %d\n",
12641261 csf(unsigned short,0xcdcdcdcd),
12651262 csf(short,0xefefefef),
1266− csfb(_Bool,0x33221100),
1267− csfb(_Bool,0x33221101));
1263+ csf(_Bool,0x33221100),
1264+ csf(_Bool,0x33221101));
1265+#endif
12681266 var3 = -10;
12691267 var1 = (char)(unsigned char)(var3 + 1);
12701268 var4 = (char)(unsigned char)(var3 + 1);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t