------- Comment #10 from jamborm at gcc dot gnu dot org 2010-06-17 15:00 ------- (In reply to comment #7) > (In reply to comment #5) > > Could you please first try to reproduce the bug with the > > -fno-tree-switch-conversion swithch? > > Using GCC 4.5.0 (tarball) > > With -fno-tree-switch-conversion switch option switch, the bug does not > appear.
Really? See below... > tailr1: > > > ;; Function void open_file(const char*, OpenMode) (_Z9open_filePKc8OpenMode) > > void open_file(const char*, OpenMode) (const char * filename, const OpenMode > rw) > { > int mode; > > <bb 2>: > switch (rw_3(D)) <default: <L1>, case 1: <L5>, case 2: <L2>, case 3: <L3>> > > <L1>: > goto <bb 6> (<L5>); > > <L2>: > goto <bb 6> (<L5>); > > <L3>: > > # mode_1 = PHI <74(2), 1(3), 3(4), 75(5)> This already looks wrong. The default branch and the branch for rw == 0 somehow got merged, which does not look correct to me (or at least not obviously correct, it seems that the compiler thinks rw can never be <0 or >3). For this input, the code and the lookup table produced by the switch conversion pass is exactly what it is supposed to be. The pass simply puts the three non-default values to the lookup table and uses the default one if rw is out of bounds. For the record, my cross (and native) compiler produces the following PHI node after the switch: # modeD.1758_1 = PHI <0(2), 74(3), 1(4), 3(5), 75(6)> You can see that the value zero is already missing in yours (I assume the C compiler works because it gets this correct, possibly among other things). > switchconv: > > > void open_file(const char*, OpenMode) (const char * filename, const OpenMode > rw) > { > char csui.2; When I use -fshort-enums my dumps specifically state unsigned char. But I assume that char is actually unsigned here by default. > const OpenMode csti.0; > int mode; > > <bb 2>: > csui.2_6 = (char) rw_3(D); > csui.2_5 = csui.2_6 + 255; > if (csui.2_5 <= 2) > goto <bb 8> (<L7>); > else > goto <bb 7> (<L6>); > > <L6>: > mode_4 = 1; > goto <bb 6> (<L8>); > > <L7>: > csti.0_8 = rw_3(D) + 255; > mode_7 = CSWTCH.1[csti.0_8]; > > # mode_1 = PHI <mode_7(8), mode_4(7)> > <L8>: > <L5>: > open (filename_9(D), mode_1); > return; > > } So if rw is zero, csui.2_5 is 255 and mode will be assigned the value 1. I assume this is not what you see happening. I am not sure if I understand the assembly snippets above 100% correctly but it seems that the C++ ones do not have any branching in them which can't be correct. This and the weird missing case in the original gimple switch statement make me think that the front-end provides some weird information about the enum type. I'd suggest generating all dumps, going through them and looking where and why the if statement disappears and how the switch statement evolved before being removed by switch conversion. Then we will have to figure out why this is happening. > > Let me know if you still need me to apply your patch or if the above info is > enough to understand the issue. I'll need some extra time to rebuild the > compiler. No, that is not necessary any longer. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44328