opt: constprop also 'cond && 0'

We didn't handle constants in logical expressions when they weren't
the first operand.  Some reordering in the loop structure is enough
to handle them.
master
Michael Matz 2016-09-26 21:21:42 +02:00
parent ca435dc2e3
commit fb933ae0eb
2 changed files with 113 additions and 62 deletions

136
tccgen.c
View File

@ -4909,37 +4909,43 @@ static void expr_land(void)
{ {
expr_or(); expr_or();
if (tok == TOK_LAND) { if (tok == TOK_LAND) {
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { int t = 0;
CType ctb, cti; for(;;) {
ctb.t = VT_BOOL; if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
cti.t = VT_INT; CType ctb;
next(); ctb.t = VT_BOOL;
gen_cast(&ctb); gen_cast(&ctb);
if (vtop->c.i) { if (vtop->c.i) {
vpop(); vpop();
expr_land(); } else {
gen_cast(&ctb); int saved_nocode_wanted = nocode_wanted;
} else { nocode_wanted = 1;
int saved_nocode_wanted = nocode_wanted; while (tok == TOK_LAND) {
nocode_wanted = 1; next();
expr_land(); expr_or();
vpop(); vpop();
nocode_wanted = saved_nocode_wanted; }
} if (t)
gen_cast(&cti); gsym(t);
} else { nocode_wanted = saved_nocode_wanted;
int t = 0; gen_cast(&int_type);
save_regs(1); break;
for(;;) { }
t = gvtst(1, t); } else {
if (tok != TOK_LAND) { if (!t)
vseti(VT_JMPI, t); save_regs(1);
break; t = gvtst(1, t);
} }
next(); if (tok != TOK_LAND) {
expr_or(); if (t)
} vseti(VT_JMPI, t);
} else
vpushi(1);
break;
}
next();
expr_or();
}
} }
} }
@ -4947,37 +4953,43 @@ static void expr_lor(void)
{ {
expr_land(); expr_land();
if (tok == TOK_LOR) { if (tok == TOK_LOR) {
if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { int t = 0;
CType ctb, cti; for(;;) {
ctb.t = VT_BOOL; if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
cti.t = VT_INT; CType ctb;
next(); ctb.t = VT_BOOL;
gen_cast(&ctb); gen_cast(&ctb);
if (vtop->c.i) { if (!vtop->c.i) {
int saved_nocode_wanted = nocode_wanted; vpop();
nocode_wanted = 1; } else {
expr_lor(); int saved_nocode_wanted = nocode_wanted;
vpop(); nocode_wanted = 1;
nocode_wanted = saved_nocode_wanted; while (tok == TOK_LOR) {
} else { next();
vpop(); expr_land();
expr_lor(); vpop();
gen_cast(&ctb); }
} if (t)
gen_cast(&cti); gsym(t);
} else { nocode_wanted = saved_nocode_wanted;
int t = 0; gen_cast(&int_type);
save_regs(1); break;
for(;;) { }
t = gvtst(0, t); } else {
if (tok != TOK_LOR) { if (!t)
vseti(VT_JMP, t); save_regs(1);
break; t = gvtst(0, t);
} }
next(); if (tok != TOK_LOR) {
expr_land(); if (t)
} vseti(VT_JMP, t);
} else
vpushi(0);
break;
}
next();
expr_land();
}
} }
} }

View File

@ -1232,6 +1232,38 @@ void optimize_out(void)
printf("ool6:%d\n", defined_function()); printf("ool6:%d\n", defined_function());
goto breakhere; goto breakhere;
} }
/* Test that constants in logical && are optimized: */
i = 0 && undefined_function();
i = defined_function() && 0 && undefined_function();
if (0 && undefined_function())
undefined_function();
if (defined_function() && 0)
undefined_function();
if (0 && 0)
undefined_function();
if (defined_function() && 0 && undefined_function())
undefined_function();
/* The same for || : */
i = 1 || undefined_function();
i = defined_function() || 1 || undefined_function();
if (1 || undefined_function())
;
else
undefined_function();
if (defined_function() || 1)
;
else
undefined_function();
if (1 || 1)
;
else
undefined_function();
if (defined_function() || 1 || undefined_function())
;
else
undefined_function();
if (1) if (1)
return; return;
printf ("oor:%d\n", undefined_function()); printf ("oor:%d\n", undefined_function());
@ -2544,6 +2576,13 @@ void sizeof_test(void)
/* And as direct sizeof argument (as unary expression): */ /* And as direct sizeof argument (as unary expression): */
printf("sizeof (struct {short i; short j;}){4,5} = %d\n", printf("sizeof (struct {short i; short j;}){4,5} = %d\n",
sizeof (struct {short i; short j;}){4,5} ); sizeof (struct {short i; short j;}){4,5} );
/* sizeof(x && y) should be sizeof(int), even if constant
evaluating is possible. */
printf("sizeof(t && 0) = %d\n", sizeof(t && 0));
printf("sizeof(1 && 1) = %d\n", sizeof(1 && 1));
printf("sizeof(t || 1) = %d\n", sizeof(t || 1));
printf("sizeof(0 || 0) = %d\n", sizeof(0 || 0));
} }
void typeof_test(void) void typeof_test(void)