towards beautiful test cases for compiler bugs
DESCRIPTION
Towards Beautiful Test Cases for Compiler Bugs. John Regehr University of Utah. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/1.jpg)
Towards Beautiful Test Cases for Compiler Bugs
John RegehrUniversity of Utah
![Page 2: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/2.jpg)
2
template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shift_right ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; } template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shr ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; }} }# 5 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2# 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp" 1# 14 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp"namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< floating_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > { typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { typedef typename dispatch::meta::as_integer<A0, unsigned>::type itype; return bitwise_cast<result_type>(shift_right(bitwise_cast<itype>(a0),a1)); } };} } }namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< integer_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > { typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { return a0 >> a1; } };} } }# 6 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2# 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp" 1# 20 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp"namespace boost { namespace simd { namespace ext{
![Page 3: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/3.jpg)
3
template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shift_right ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; } template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shr ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; }} }# 5 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2# 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp" 1# 14 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp"namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< floating_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > { typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { typedef typename dispatch::meta::as_integer<A0, unsigned>::type itype; return bitwise_cast<result_type>(shift_right(bitwise_cast<itype>(a0),a1)); } };} } }namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< integer_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > { typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { return a0 >> a1; } };} } }# 6 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2# 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp" 1# 20 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp"namespace boost { namespace simd { namespace ext{
From GCC PR 50800:“Testcase is [here] (couldn't attach it due to bugzilla size restrictions)”
![Page 4: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/4.jpg)
4
template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shift_right ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; } template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shr ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; }} }# 5 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2# 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp" 1# 14 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp"namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< floating_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > { typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { typedef typename dispatch::meta::as_integer<A0, unsigned>::type itype; return bitwise_cast<result_type>(shift_right(bitwise_cast<itype>(a0),a1)); } };} } }namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< integer_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > { typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { return a0 >> a1; } };} } }# 6 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2# 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp" 1# 20 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp"namespace boost { namespace simd { namespace ext{
From GCC PR 50800:“Testcase is [here] (couldn't attach it due to bugzilla size restrictions)”
Next comment:“That you couldn't attach it should tell you something…”
![Page 5: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/5.jpg)
5
template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shift_right ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; } template< class A0 , class A1> __attribute__((always_inline)) typename boost::dispatch::meta::call<tag::shift_right_( A0 const& , A1 const& )>::type shr ( A0 const& a0 , A1 const& a1 ) { typename boost::dispatch::make_functor<tag::shift_right_, A0>::type callee; return callee( a0 , a1);; }} }# 5 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2# 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp" 1# 14 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/scalar/shift_right.hpp"namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< floating_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< floating_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > { typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { typedef typename dispatch::meta::as_integer<A0, unsigned>::type itype; return bitwise_cast<result_type>(shift_right(bitwise_cast<itype>(a0),a1)); } };} } }namespace boost { namespace simd { namespace ext{ } } } namespace boost { namespace dispatch { namespace meta { template< class A0 , class A1> __attribute__((always_inline)) boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> >) , tag::cpu_ > dispatching( boost::simd::tag::shift_right_, tag::cpu_ , scalar_< integer_<A0> > const , scalar_< integer_<A1> > const , adl_helper = adl_helper() ) { boost :: simd :: ext :: implement< boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_ > that; return that; } } } } namespace boost { namespace simd { namespace ext { template< class A0 , class A1 , class Dummy > struct implement < boost::simd::tag::shift_right_( scalar_< integer_<A0> > , scalar_< integer_<A1> > ) , tag::cpu_, Dummy > { typedef A0 result_type; inline result_type operator()( A0 const& a0 , A1 const& a1 ) const { return a0 >> a1; } };} } }# 6 "/home/gaunard/build/may_alias/include/boost/simd/toolbox/operator/include/functions/shift_right.hpp" 2# 1 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp" 1# 20 "/home/gaunard/dev/may_alias/modules/boost/simd/operator/include/boost/simd/toolbox/operator/functions/simd/common/shift_right.hpp"namespace boost { namespace simd { namespace ext{
From GCC PR 50800:“Testcase is [here] (couldn't attach it due to bugzilla size restrictions)”
Next comment:“That you couldn't attach it should tell you something…”Next comment:
203 KB reduced test case attached
![Page 6: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/6.jpg)
6
(safe_47 (((g_1161 ^ 0x2893L), (((safe_9 ((!l_1747),
((l_1749 = func_37 (func_58
((l_1748, 4294967293UL), g_110, l_1168, p_7, l_1747), g_381, p_9)),
g_894))) != l_1747) <= p_10)), p_8))),g_11) <= p_7)), g_1315, p_8), 10))) > 4UL),
0x93L)) ^ g_1161))) <= l_1750), p_8), g_458); g_1122 = (l_1749
&& func_37 (l_1750, (g_1161 = ((safe_17 (((safe_60 (l_1755, 4)) |
(g_703, (safe_55 ((p_10, 3UL), p_7)))),((safe_51 ((safe_42 (0UL, ((l_1747 != 0x3AL) < g_28))))) | 0xF862D3BEL))) != 0xC7L)),
g_1487)); g_146 = 0xBC806FC8L; l_1788 =
func_24 (((safe_13 ((~ (((g_458 !=
(safe_54 (((~ (l_1749 = (safe_43 ((safe_14
((((safe_62 ((safe_4 ((safe_63
(((l_1750 = 1L), (safe_59 (l_1168, 1))), (((p_10 = func_46 (func_46
(l_1749, g_894, (safe_23 (l_1749,
(l_1167 = g_1161))), ((l_1469 =
![Page 7: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/7.jpg)
7
(safe_47 (((g_1161 ^ 0x2893L), (((safe_9 ((!l_1747),
((l_1749 = func_37 (func_58
((l_1748, 4294967293UL), g_110, l_1168, p_7, l_1747), g_381, p_9)),
g_894))) != l_1747) <= p_10)), p_8))),g_11) <= p_7)), g_1315, p_8), 10))) > 4UL),
0x93L)) ^ g_1161))) <= l_1750), p_8), g_458); g_1122 = (l_1749
&& func_37 (l_1750, (g_1161 = ((safe_17 (((safe_60 (l_1755, 4)) |
(g_703, (safe_55 ((p_10, 3UL), p_7)))),((safe_51 ((safe_42 (0UL, ((l_1747 != 0x3AL) < g_28))))) | 0xF862D3BEL))) != 0xC7L)),
g_1487)); g_146 = 0xBC806FC8L; l_1788 =
func_24 (((safe_13 ((~ (((g_458 !=
(safe_54 (((~ (l_1749 = (safe_43 ((safe_14
((((safe_62 ((safe_4 ((safe_63
(((l_1750 = 1L), (safe_59 (l_1168, 1))), (((p_10 = func_46 (func_46
(l_1749, g_894, (safe_23 (l_1749,
(l_1167 = g_1161))), ((l_1469 =
Exposes an LLVM miscompilation bug
Part of an 89 KB program randomly generated by Csmith
![Page 8: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/8.jpg)
8
(safe_47 (((g_1161 ^ 0x2893L), (((safe_9 ((!l_1747),
((l_1749 = func_37 (func_58
((l_1748, 4294967293UL), g_110, l_1168, p_7, l_1747), g_381, p_9)),
g_894))) != l_1747) <= p_10)), p_8))),g_11) <= p_7)), g_1315, p_8), 10))) > 4UL),
0x93L)) ^ g_1161))) <= l_1750), p_8), g_458); g_1122 = (l_1749
&& func_37 (l_1750, (g_1161 = ((safe_17 (((safe_60 (l_1755, 4)) |
(g_703, (safe_55 ((p_10, 3UL), p_7)))),((safe_51 ((safe_42 (0UL, ((l_1747 != 0x3AL) < g_28))))) | 0xF862D3BEL))) != 0xC7L)),
g_1487)); g_146 = 0xBC806FC8L; l_1788 =
func_24 (((safe_13 ((~ (((g_458 !=
(safe_54 (((~ (l_1749 = (safe_43 ((safe_14
((((safe_62 ((safe_4 ((safe_63
(((l_1750 = 1L), (safe_59 (l_1168, 1))), (((p_10 = func_46 (func_46
(l_1749, g_894, (safe_23 (l_1749,
(l_1167 = g_1161))), ((l_1469 =
Part of an 89 KB program randomly generated by Csmith
Exposes an LLVM miscompilation bug
Csmith is our C compiler fuzzer
~425 compiler bugs discovered and reported so far
http://embed.cs.utah.edu/csmith/
![Page 9: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/9.jpg)
9
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
$ clang -O1 foo.c ; ./a.out 0$ clang -O2 foo.c ; ./a.out 1
![Page 10: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/10.jpg)
10
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
$ clang -O1 foo.c ; ./a.out 0$ clang -O2 foo.c ; ./a.out 1
Reported as LLVM PR 12189 on 3/5/2012, fixed same day
![Page 11: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/11.jpg)
11
int printf (const char *, …);
char f[] = { -9L };
int main (void) { printf ("%d\n", 255 | f[0]); }
Intel CC 12.0.5 for x86-64 is wrong at “-Ofast -ipo”
![Page 12: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/12.jpg)
12
int printf (const char *, ...);
const union { short f1; int f2 : 13;} a = { 30155 };
int main (void) { printf ("%d\n", a.f1); printf ("%d\n", a.f2); return 0;}
GCC 4.4.3 from Ubuntu 10.04 LTS for x86-64 is wrong at -O1
![Page 13: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/13.jpg)
13
int printf (const char *, ...);
int b;
static struct S0 { int f2 : 1;} c;
int main (void) { b = -1 ^ c.f2; printf ("%d\n", b);}
GCC from mid-Feb 2012 for x86-64 is wrong at -O0(PR 52209)
![Page 14: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/14.jpg)
14
Beautiful test case ==1. Small (but not obfuscated)2. Well-defined3. Unambiguously elicits bad behavior4. Makes the compiler bug obvious
Not all bugs have beautiful test cases
![Page 15: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/15.jpg)
15
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
Delta Debugging algorithm “ddmin” ==• Greedy search• Delete chunks• Test results for
“interestingness”• Keep reducing
granularity
![Page 16: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/16.jpg)
16
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
ddmin ==• Greedy search• Delete chunks• Test for
“interestingness”• Keep reducing
granularity
Is this still interesting?
![Page 17: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/17.jpg)
17
#!/bin/bashclang -O1 test.c &&\./a.out > out1.txt &&\clang -O2 test.c &&\./a.out > out2.txt &&\! diff out1.txt out2.txt
![Page 18: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/18.jpg)
18
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
ddmin ==• Greedy search• Delete chunks• Test for
“interestingness”• Keep reducing
granularity
Assume not interesting, so we backtrack
![Page 19: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/19.jpg)
19
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
ddmin ==• Greedy search• Delete chunks• Test for
“interestingness”• Keep reducing
granularity
![Page 20: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/20.jpg)
20
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
ddmin ==• Greedy search• Delete chunks• Test for
“interestingness”• Keep reducing
granularity
![Page 21: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/21.jpg)
21
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
ddmin ==• Greedy search• Delete chunks• Test for
“interestingness”• Keep reducing
granularity
![Page 22: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/22.jpg)
22
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
ddmin ==• Greedy search• Delete chunks• Test for
“interestingness”• Keep reducing
granularity
![Page 23: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/23.jpg)
23
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
ddmin ==• Greedy search• Delete chunks• Test for
“interestingness”• Keep reducing
granularity
![Page 24: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/24.jpg)
24
short a;int b, d, k, l, m;
int fn1 (short p1, int p2) { return p1 - p2;}
int fn2 (short p1) { return p1 == 0 || a == 0 ? a : a % p1;}
int fn3 (int p1, unsigned short p2) { return p2 == 0 ? 0 : p1 % p2;}
void fn4 (unsigned char p1) { if (p1) b = 1;}
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
ddmin ==• Greedy search• Delete chunks• Test for
“interestingness”• Keep reducing
granularity
![Page 25: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/25.jpg)
25
• Problem: ddmin gets stuck–Output is often not beautiful
• Our premise: –The Delta Debugging concept is sound –But ddmin is too hard-coded, inflexible
![Page 26: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/26.jpg)
26
Generalized Delta Debugging
1. One or more transformations– E.g. “remove chunks of text”
2. Interestingness test3. Fitness function– E.g. “prefer smaller test cases”
4. Search algorithm– E.g. “greedy”
![Page 27: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/27.jpg)
27
Generalized Delta Debugging
1. One or more transformations– E.g. “remove chunks of text”
2. Interestingness test3. Fitness function– E.g. “prefer smaller test cases”
4. Search algorithm– E.g. “greedy”
![Page 28: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/28.jpg)
28
C-Reduce: A Generalized Delta Debugger• Fixpoint computation• Parameterized by– Interestingness test– Plugins that perform transformations
Plugins are iterators implementing:• reset()• advance()• transform(file)
![Page 29: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/29.jpg)
29
void fn5 (p1) { short n = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
![Page 30: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/30.jpg)
30
void fn5 (p1) { short 0 = 60018; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
![Page 31: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/31.jpg)
31
void fn5 (p1) { short n = 0; k = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
![Page 32: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/32.jpg)
32
void fn5 (p1) { short n = 60018; 0 = fn2 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
![Page 33: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/33.jpg)
33
void fn5 (p1) { short n = 60018; k = 0 (p1); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
![Page 34: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/34.jpg)
34
void fn5 (p1) { short n = 60018; k = fn2 (0); d = k != 0; l = fn1 (d, n); m = fn3 (l, p1); fn4 (m);}
int main () { fn5 (2); printf ("%d\n", b); return 0;}
![Page 35: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/35.jpg)
35
Example transformations:• Remove chunks of text (like ddmin)• C-specific peephole transformations–0xfeedbeefULL 1– x ^= y x = y – (x + 1) x + 1–while (…) if (…)– x ? y : z y
C-Reduce has 49 plugins so far
![Page 36: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/36.jpg)
36
• Some transformations make coordinated changes across different parts of the program– Inline a function call– Scalar replacement of aggregates–Un-nest nested function calls–Remove dead arguments–Make function return void–Reduce array dimension or pointer level– Shorten identifier name
• These use Clang as a rewriter
![Page 37: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/37.jpg)
37
transformationtransformationtransformationtransformationtransformation
current test case
interesting?
yes
no
![Page 38: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/38.jpg)
38
Beautiful test case ==1. Small (but not obfuscated)2. Well-defined3. Unambiguously elicits bad behavior4. Makes the compiler bug obvious
![Page 39: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/39.jpg)
39
#include <iostream>using namespace std;int r[3], x[3], y[3];int main() { int xa=2,ya=5,xb=4,yb=2,n=3; x[0] = 3; x[1] = 5; x[2] = 1; y[0] = 1; y[1] = 3; y[2] = 3; r[0] = 2; r[1] = 1; r[2] = 2; int tcount = 0; for (int k=min(xa,xb); k<=max(xa,xb); k++) { bool found1,found2 = false; for (int j=0; j<n; j++) { if (((k-x[j])*(k-x[j])+(y[j]-ya)*(y[j]-ya))<=r[j]*r[j]) { found1 = true; } if (((k-x[j])*(k-x[j])+(y[j]-yb)*(y[j]-yb))<=r[j]*r[j]) { found2 = true; } if (found1 && found2) break; } if (!found1) tcount++; if (!found2) tcount++; } cout << tcount << endl; return 0; }
GCC PR 51962
![Page 40: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/40.jpg)
40
#include <iostream>using namespace std;int r[3], x[3], y[3];int main() { int xa=2,ya=5,xb=4,yb=2,n=3; x[0] = 3; x[1] = 5; x[2] = 1; y[0] = 1; y[1] = 3; y[2] = 3; r[0] = 2; r[1] = 1; r[2] = 2; int tcount = 0; for (int k=min(xa,xb); k<=max(xa,xb); k++) { bool found1,found2 = false; for (int j=0; j<n; j++) { if (((k-x[j])*(k-x[j])+(y[j]-ya)*(y[j]-ya))<=r[j]*r[j]) { found1 = true; } if (((k-x[j])*(k-x[j])+(y[j]-yb)*(y[j]-yb))<=r[j]*r[j]) { found2 = true; } if (found1 && found2) break; } if (!found1) tcount++; if (!found2) tcount++; } cout << tcount << endl; return 0; }
GCC PR 51962
Bug report says:
“Compile the following simple code without -O3, and run.
Now compile it with -O3 option (for optimization), run again.
Surprisingly 2 different outputs appear.”
![Page 41: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/41.jpg)
41
#include <iostream>using namespace std;int r[3], x[3], y[3];int main() { int xa=2,ya=5,xb=4,yb=2,n=3; x[0] = 3; x[1] = 5; x[2] = 1; y[0] = 1; y[1] = 3; y[2] = 3; r[0] = 2; r[1] = 1; r[2] = 2; int tcount = 0; for (int k=min(xa,xb); k<=max(xa,xb); k++) { bool found1,found2 = false; for (int j=0; j<n; j++) { if (((k-x[j])*(k-x[j])+(y[j]-ya)*(y[j]-ya))<=r[j]*r[j]) { found1 = true; } if (((k-x[j])*(k-x[j])+(y[j]-yb)*(y[j]-yb))<=r[j]*r[j]) { found2 = true; } if (found1 && found2) break; } if (!found1) tcount++; if (!found2) tcount++; } cout << tcount << endl; return 0; }
GCC PR 51962
Bug report says:
“Compile the following simple code without -O3, and run.
Now compile it with -O3 option (for optimization), run again.
Surprisingly 2 different outputs appear.”
GCC developer responds:
“You do not initialise found1.”
PR 51962 is RESOLVED INVALID
And this person may have a hard time getting someone to read his next bug report
![Page 42: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/42.jpg)
42
#include <iostream>using namespace std;int r[3], x[3], y[3];int main() { int xa=2,ya=5,xb=4,yb=2,n=3; x[0] = 3; x[1] = 5; x[2] = 1; y[0] = 1; y[1] = 3; y[2] = 3; r[0] = 2; r[1] = 1; r[2] = 2; int tcount = 0; for (int k=min(xa,xb); k<=max(xa,xb); k++) { bool found1,found2 = false; for (int j=0; j<n; j++) { if (((k-x[j])*(k-x[j])+(y[j]-ya)*(y[j]-ya))<=r[j]*r[j]) { found1 = true; } if (((k-x[j])*(k-x[j])+(y[j]-yb)*(y[j]-yb))<=r[j]*r[j]) { found2 = true; } if (found1 && found2) break; } if (!found1) tcount++; if (!found2) tcount++; } cout << tcount << endl; return 0; }
GCC PR 51962
![Page 43: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/43.jpg)
43
• C99 has –191 kinds of undefined behavior–52 kinds of unspecified behavior
• Code in a bug report must not execute these behaviors
• ddmin and C-Reduce tend to introduce these behaviors
![Page 44: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/44.jpg)
44
#!/bin/bashis_valid_c99 test.c &&\clang -O1 test.c &&\./a.out > out1.txt &&\clang -O2 test.c &&\./a.out > out2.txt &&\! diff out1.txt out2.txt
![Page 45: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/45.jpg)
45
Validity checkers:
KCC: executable semantics for C99http://code.google.com/p/c-semantics/
Frama-C: static analyzer that supports an interpreter modehttp://frama-c.com/
![Page 46: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/46.jpg)
46
Median size output from reducers
• For 57 compiler-crash bugs– ddmin*: 8.6 KB– C-Reduce: 0.33 KB
• For 43 wrong-code bugs– ddmin*: 6.5 KB– C-Reduce: 0.51 KB
*http://delta.tigris.org/
![Page 47: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/47.jpg)
47
• Reduction fails when compiler is non-deterministic–Usually due to memory unsafety + ASLR
• Reduction works poorly when compiler bug stems from a resource overflow– Infinite loop, memory leak, register spill
![Page 48: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/48.jpg)
48
Can C-Reduce create reportable test cases from proprietary codes?• We hope so• Clearly “declassification” has to be
done on a case-by-case basis• We would love to get feedback
about successes and failures
![Page 49: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/49.jpg)
49
• Does C-Reduce work for C++ code?–Yes, but not (yet) very well
• C++-specific transformations are needed–Template instantiation–Namespace and class hierarchy flattening
• Problem: No validity checker for C++
![Page 50: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/50.jpg)
50
• Factoring the transformations out of a delta debugger is a good idea
• C-Reduce can (sometimes) produce beautiful test cases
• Ensuring validity of test cases is hard
![Page 51: Towards Beautiful Test Cases for Compiler Bugs](https://reader036.vdocuments.net/reader036/viewer/2022062520/5681645f550346895dd63911/html5/thumbnails/51.jpg)
51
C-Reduce is here:https://github.com/csmith-project/creduce