Bug 25724 - Emits call to __cmpdi2 for long long comparison in switches
Summary: Emits call to __cmpdi2 for long long comparison in switches
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.1.0
: P3 enhancement
Target Milestone: 4.2.0
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2006-01-09 14:31 UTC by Richard Biener
Modified: 2006-02-13 18:51 UTC (History)
5 users (show)

See Also:
Host:
Target: s390-ibm-linux
Build:
Known to work:
Known to fail: 3.3.3 3.4.0 4.0.0 4.1.0 4.2.0 3.1 4.0.3
Last reconfirmed: 2006-01-09 15:14:35


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Richard Biener 2006-01-09 14:31:29 UTC
The kernel for s390 (and ppc) currently drags in __cmpdi2 from libgcc with
the following reduced testcase even though s390 is supposed to have an 8
byte comparison opcode and archs such as i686 generate bit-twiddling for
this unsupported case (admittandly not from ifcvt, but from some define-expand
hackery), i.e. ll[0] | ll[1] == 0.

void foo(void);
int dcache_readdir(long long ll)
{
    switch(ll) {
        case 0:
          foo();
    }
}
Comment 1 Andrew Pinski 2006-01-09 14:33:08 UTC
This is no way critical at all.
Comment 2 Andrew Pinski 2006-01-09 14:38:05 UTC
Confirmed, this is just a missed optimization and not a regression at best.  If the kernel is using long long on a 32bit target, it needs all support functions including __cmpdi2.
Comment 3 Richard Biener 2006-01-09 14:41:50 UTC
Using

void foo(void);
int dcache_readdir(long long ll)
{
    if (ll == 0)
          foo();
}

the correct bit-twiddling is generated...

So it looks like a generic switch expand issue.
Comment 4 Pawel Sikora 2006-01-09 15:46:10 UTC
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21237
Comment 5 Pawel Sikora 2006-01-09 15:48:34 UTC
(In reply to comment #4)
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21237

oops, I accidentally posted this link:(
Comment 6 Andreas Krebbel 2006-01-09 18:26:23 UTC
As far as I know the kernel guys rely on the fact that gcc can 
handle DImode operations without calling libgcc. As Richard pointed out 
this only fails in this case because the conditional jump is emitted
differently for case nodes.

A normal DImode compare (on 32bit) is split into SImode compares before 
emit_cmp_and_jump_insns is called. This is done by do_jump_by_parts_equality.

emit_case_nodes in turn calls do_jump_if_equal which calls 
emit_cmp_and_jump_insns with DImode operands.

So I think using the dojump.c machinery in emit_case_nodes should be the
way to go - right?!
Comment 7 Richard Biener 2006-01-10 09:27:07 UTC
Yes, this sounds like the way to go.
Comment 8 Roger Sayle 2006-02-13 01:55:40 UTC
Subject: Bug 25724

Author: sayle
Date: Mon Feb 13 01:55:37 2006
New Revision: 110906

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=110906
Log:

	PR middle-end/25724
	* dojump.c (do_jump): Call do_compare_rtx_and_jump.
	(do_jump_parts_zero_rtx): New function renamed from
	do_jump_parts_equality_rtx.  Made static.  Add a mode argument.
	(do_jump_parts_equality_rtx): New function split out from
	do_jump_parts_equality.  Old implementation renamed as above.
	Call do_jump_parts_zero_rtx if either operand is zero.
	(do_jump_parts_equality): Call do_jump_parts_equality_rtx to
	do all of the heavy lifting.
	(do_compare_rtx_and_jump): Handle multi-word comparisons by
	calling either do_jump_by_parts_greater_rtx or
	do_jump_by_parts_equality_rtx.
	* expr.h (do_jump_by_parts_equality_rtx): Remove prototype.
	* expmed.c (do_cmp_and_jump): Now multi-word optimization has
	moved to do_compare_rtx_and_jump, call it directly.
	* stmt.c (do_jump_if_equal): Remove static prototype.  Add a
	mode argument.  Call do_compare_rtx_and_jump.
	(emit_case_nodes): Update calls to do_jump_if_equal.


Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/dojump.c
    trunk/gcc/expmed.c
    trunk/gcc/expr.h
    trunk/gcc/stmt.c

Comment 9 roger 2006-02-13 18:51:34 UTC
This has now been fixed on mainline.