User account creation filtered due to spam.

Bug 40748 - simple switch/case, if/else and arithmetics result in different code
Summary: simple switch/case, if/else and arithmetics result in different code
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.5.0
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: missed-optimization
Depends on:
Blocks:
 
Reported: 2009-07-14 17:09 UTC by Zdenek Sojka
Modified: 2017-06-18 19:55 UTC (History)
3 users (show)

See Also:
Host: x86_64-pc-linux-gnu
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2009-07-15 09:34:55


Attachments
testcase (181 bytes, text/plain)
2009-07-14 17:11 UTC, Zdenek Sojka
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Zdenek Sojka 2009-07-14 17:09:16 UTC
Tested r149624, 4.4.0 and 4.3.3

# ./gcc -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../configure --enable-languages=c,c++ --prefix=/mnt/svn/gcc-trunk/build/
Thread model: posix
gcc version 4.5.0 20090714 (experimental) (GCC)

4.4.0 and 4.5 have better behaviour in the case of "switch"

The following code:
-------------------------------
unsigned f1(unsigned i)
{
	switch (i) {
		case 0: return 0;
		case 1: return 1;
		case 2: return 2;
		case 3: return 3;
		default: return 4;
	}
}

unsigned f2(unsigned i)
{
	if (i == 0) return 0;
	if (i == 1) return 1;
	if (i == 2) return 2;
	if (i == 3) return 3;
	return 4;
}

unsigned f3(unsigned i)
{
	return i < 4 ? i : 4;
}
-------------------------------

f1(), f2() and f3() do the same, but the resulting code differs a lot.
Comment 1 Zdenek Sojka 2009-07-14 17:11:21 UTC
Created attachment 18195 [details]
testcase

Even at -O3, f1() and f2() don't have the same code as f3().
Comment 2 Richard Biener 2009-07-15 09:34:55 UTC
switch-conversion could try to handle this.  Generally perfect hashing during
switch expansion is another thing.
Comment 3 Marc Glisse 2017-06-18 19:55:35 UTC
We also miss the even simpler case that should be optimized to "return n;"

int foo(int n){
    switch(n){
        case 0:
            return 0;
        case 1:
            return 1;
        case 2:
            return 2;
        case 3:
            return 3;
        default:
            __builtin_unreachable();
    }
}

llvm performs the expected optimization in both cases.