1/* Verify that simple indirect calls are inlined even without early 2 inlining.. */ 3/* { dg-do run } */ 4/* { dg-options "-O3 -fdump-ipa-inline -fno-early-inlining -fno-ipa-icf" } */ 5 6extern void abort (void); 7 8struct S 9{ 10 int i; 11 void (*f)(struct S *); 12 int j,k,l; 13}; 14 15struct Z 16{ 17 unsigned u; 18 void (*f)(struct Z *, int); 19 struct Z *next; 20}; 21 22static struct Z *gz; 23static struct S *gs; 24static int gr = 111; 25char gc[1024]; 26 27static __attribute__ ((noinline, noclone)) struct S * 28get_s (void) 29{ 30 return (struct S *) &gc; 31} 32 33 34static void wrong_target_1 (struct S *s) 35{ 36 abort (); 37} 38 39static void wrong_target_2 (struct S *s) 40{ 41 abort (); 42} 43 44static void wrong_target_3 (struct S *s) 45{ 46 abort (); 47} 48 49static void good_target (struct Z *z, int i) 50{ 51 gr = 0; 52} 53 54static void good_target_3 (struct S *s) 55{ 56 gr = 0; 57} 58 59static void g1 (struct S *s) 60{ 61 struct Z *z = (struct Z*) s; 62 z->f (z, 8); 63} 64 65static void f1 (struct S *s) 66{ 67 gz->f = good_target; 68 g1 (s); 69} 70 71static void g2 (struct Z *z) 72{ 73 z->f (z, 8); 74} 75 76static void f2 (struct S *s) 77{ 78 gz->f = good_target; 79 g2 ((struct Z*) s); 80} 81 82static void g3 (struct S *s) 83{ 84 s->f (s); 85} 86 87static void h3 (struct Z *z) 88{ 89 gs->f = good_target_3; 90 g3 ((struct S *) z); 91} 92 93static void f3 (struct S *s) 94{ 95 h3 ((struct Z*) s); 96} 97 98int main (int argc, char **argv) 99{ 100 struct S *s = get_s(); 101 s->i = 5678; 102 s->f = wrong_target_1; 103 s->j = 1234; 104 gz = (struct Z *) s; 105 f1 (s); 106 107 s = get_s(); 108 gz = (struct Z *) s; 109 s->i = 9999; 110 s->f = wrong_target_1; 111 f2 (s); 112 113 s = get_s(); 114 gs = s; 115 s->i = 9999; 116 s->f = wrong_target_3; 117 f3 (s); 118 119 return gr; 120} 121 122 123/* { dg-final { scan-ipa-dump-not "wrong_target\[^\\n\]*inline copy in" "inline" } } */ 124/* { dg-final { cleanup-ipa-dump "inline" } } */ 125