Optimize Code Incorrect.... CW 7.1.1

cancel
Showing results for 
Search instead for 
Did you mean: 

Optimize Code Incorrect.... CW 7.1.1

840 Views
Contributor III

Hi All, I have a rather large project (30 million lines of code) in C and C++ that I use CW 7.1.1 with.  In fixing a defect in the code, I have found a rather annoying problem in one of my classes, here's some sample code.

 

In all my functions across the clases for a specific external data type (that is more like a static, than it is belonging to a class), the optimizer always optimizes out the code.  For example, thiis is the code:

 

enum

{

   value1 = 1,

   value2 = 2

};

 

int val;

 

GetVal(&val);

 

if (val == value1)

{

   // do this, assume valid code here

}

else

{

  // do that, assume valid code here

}

 

For this, when I call GetVal, the value in the running code can be 1 or 2 depending on conditions.  However, the IF portion above is always optimized out while the else is the code that is left to run every time.

 

If tried switch it so that it is if (val == value2) and it gives me the same thing.  I tried using the values such as 1 and 2 instead of an enum, but still uses the else only (in fact when debugging, you can't even set a breakpoint in the if portion).

 

This is the same in all 7 locations in the code that the above is used.  We use many other get functions performing a similar task and then do comparions to an enum, but they always are left intact (if or else would run).

 

Can anyone offer suggestions to why the compiler is optimizing it out?  The if statement is valid, the data stored in the variable is valid, the enum is valid, the if statement itself is valid and the code in the IF and ELSE is valid.

 

I can't figure it out.

Labels (1)
0 Kudos
6 Replies

8 Views
NXP Employee
NXP Employee

Check the preprocessor output, could be some name collision.

Appart from the usual suspects (like using assignment instead of a comparison "if (val = value1)", additional semicolons "if (val = value1); {}" , &'s without braces "if (i & 4 == 0)"

it is a bit hard to see the problem without any real code.

Try to simplify the code as much as you can still see the problem, then post that here.

 

Also do you see this behavior only with optimizations on or also in non optimized builds?

 

Is the variable initialized?

Does GetVal assign a value in all cases? Is GetVal inlined? Is inlining enabled?

 

Daniel

0 Kudos

8 Views
Contributor III

yes, the variable is always initialized to something....

 

            if (by_Volume_Comma_Position == eCFG_TW_TRANS_VOLUME_FOLLOW_DECIMAL)
            {

                iAdjust = Vol_Layout - (VOLUME_SIZE - (byComma & 0x7f));
            }
            else
            {
                iAdjust = 3 - (VOLUME_SIZE - (byComma & 0x7f));
            }

 

 

Wtih this, always the else is the only thing left in.

 

            if (by_Volume_Comma_Position == 1)
            {

                iAdjust = Vol_Layout - (VOLUME_SIZE - (byComma & 0x7f));
            }
            else
            {
                iAdjust = 3 - (VOLUME_SIZE - (byComma & 0x7f));
            }

 

Wtih this, always the else is the only thing left in.

 

            if (by_Volume_Comma_Position == 2)
            {

                iAdjust = Vol_Layout - (VOLUME_SIZE - (byComma & 0x7f));
            }
            else
            {
                iAdjust = 3 - (VOLUME_SIZE - (byComma & 0x7f));
            }

 

 

Wtih this, always the else is the only thing left in.

 

            by_Volume_Comma_Position = 2;

            if (by_Volume_Comma_Position == 2)
            {

                iAdjust = Vol_Layout - (VOLUME_SIZE - (byComma & 0x7f));
            }
            else
            {
                iAdjust = 3 - (VOLUME_SIZE - (byComma & 0x7f));
            }

 

 Even with this, the else is ALWAYS the only thing left in, and this is forcing the variable to be what it is checking for....

 

This makes no sense.

0 Kudos

8 Views
Contributor III

But, this works and links on the IF statement, and not the else

 

if (2 == 2)
{

                iAdjust = Vol_Layout - (VOLUME_SIZE - (byComma & 0x7f));
}
else
{
                iAdjust = 3 - (VOLUME_SIZE - (byComma & 0x7f));
}

 

So that's a good sign, sort of

0 Kudos

8 Views
Contributor III

Ok, strange.... as said before, this fails and only else is linked in.....

 

GetVal(&Vol_Layout)

GetVal(&by_Volume_Comma_Position);

if (by_Volume_Comma_Position == eCFG_TW_TRANS_VOLUME_FOLLOW_DECIMAL)
{

                iAdjust = Vol_Layout - (VOLUME_SIZE - (byComma & 0x7f));
}
else
{
                iAdjust = 3 - (VOLUME_SIZE - (byComma & 0x7f));
}

 

 

 

So, I tried a ton of things this morning, and this works for linking in both IF and ELSE:

GetVal(&by_Volume_Comma_Position)

if (by_Volume_Comma_Position == eCFG_TW_TRANS_VOLUME_FOLLOW_DECIMAL)
{


                GetVal(&Vol_Layout);

                iAdjust = Vol_Layout - (VOLUME_SIZE - (byComma & 0x7f));
}
else
{
                iAdjust = 3 - (VOLUME_SIZE - (byComma & 0x7f));
}

 

 

So, simply by moving the retrieval of a value used inside the IF statement to the IF statement itself, seems to fix the problem.  btu I would stil like to know root cause.  This is a work around, sure, but duplicating this kind of code does not limit code size when the value Vol_Layout is also needed outside this IF statement (and before this if statement is called)

0 Kudos

8 Views
Contributor III

ok, I found a better workaround, but still, does not explain what is going on in the first place

 

// Fixed == 1

GetVal(&Vol_Layout);

if (by_Volume_Comma_Position == eCFG_TW_TRANS_VOLUME_FIXED)
{


                Vol_Layout = 3;
}

                iAdjust = Vol_Layout - (VOLUME_SIZE - (byComma & 0x7f));

 

0 Kudos

8 Views
NXP Employee
NXP Employee

Did you look at the preprocessor output? Are the optimizations enabled?

If Vol_Layout would be 3, then the if and the else would also contain the same code, explaining why the compiler only picks one. Also just to have asked, the code does behave incorrectly, it does not just step as it would, right?

 

In the end, without being able to see the real thing I don't think it is possible to remote-diagnose the issue.

I would suggest that you file a service request for further investigation.

 

Daniel

0 Kudos