Bug 9707 - Unnecessary range test in switches with less than 4 cases
Summary: Unnecessary range test in switches with less than 4 cases
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 3.3
: P3 enhancement
Target Milestone: 4.0.0
Assignee: Kazu Hirata
URL:
Keywords: missed-optimization, patch
Depends on:
Blocks:
 
Reported: 2003-02-14 16:46 UTC by gertom
Modified: 2004-03-25 16:27 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2004-02-16 13:48:40


Attachments
switch.tar.gz (731 bytes, application/x-gzip )
2003-05-21 15:17 UTC, gertom
Details

Note You need to log in before you can comment on or make changes to this bug.
Description gertom 2003-02-14 16:46:00 UTC
When a switch has less than 4 cases gcc tests for the middle-case-value and makes an additional less-greater check instead of immediately evaluating the other case-values. If there are more case branches in the switch, this kind of checking would speed up the search of the corresponding case branch (but those switches are solved with jump-tables anyway). But for only a few case branches, the direct equality checks would be better.

Release:
gcc version 3.3 20030210 (prerelease)

Environment:
BUILD & HOST: Linux 2.4.20 i686 unknown
TARGET: arm-unknown-elf

How-To-Repeat:
arm-elf-gcc -S -g0 -Os -o 01_3d.s ./01_3d.i

//01_3d.i

# 1 "01_3d.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "01_3d.c"
unsigned int g;
int main ()
{
  int r;
  switch (r) {
    case 1:
             g=11;
        break;
    case 2:
             g=12;
        break;
    case 3:
             g=13;
        break;
    default:
             g=20;
        break;
  }
  return 0;
}
Comment 1 Andrew Pinski 2003-05-28 21:01:36 UTC
You are right, gcc should not be using range tests for this case.
Comment 2 Andrew Pinski 2003-08-04 04:00:32 UTC
Here is a better version of this (f should produce the same code as g)
int f (int r)
{
  switch (r) {
    case 1:
             return 11;
    case 2:
             return 12;
    case 3:
             return 13;
    default:
             return 20;
  }
}
int g(int r)
{
        if(r==1)
                return 11;
        else if (r==2)
                return 12;
        else if (r==3)
                return 13;
        else 
                return 30;
}
Comment 3 Andrew Pinski 2004-02-16 13:48:39 UTC
This is caused by the TREE to RTL expanders so moving to middle-end.
Comment 4 Kazu Hirata 2004-03-24 22:30:33 UTC
I've got a patch in testing.
Comment 5 Kazu Hirata 2004-03-25 04:46:50 UTC
Patch:

http://gcc.gnu.org/ml/gcc-patches/2004-03/msg02065.html
Comment 6 GCC Commits 2004-03-25 16:16:52 UTC
Subject: Bug 9707

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	kazu@gcc.gnu.org	2004-03-25 16:16:43

Modified files:
	gcc            : ChangeLog stmt.c 

Log message:
	PR optimization/9707.
	* stmt.c (emit_case_nodes): Emit equality comparisons instead
	of recursing if both children are single-valued cases with no
	children.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.3288&r2=2.3289
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/stmt.c.diff?cvsroot=gcc&r1=1.350&r2=1.351

Comment 7 Kazu Hirata 2004-03-25 16:27:57 UTC
I just checked in the patch.