IBM Support

IZ99244: INCORRECT 'IF' BRANCH WITH -O2

Fixes are available

May 2011 PTF for XL C for AIX, V11.1
May 2011 PTF for XL C/C++ for AIX, V11.1
August 2011 PTF for XL C/C++ for AIX, V11.1
November 2011 PTF for XL C/C++ for AIX, V11.1
January 2012 PTF for XL C for AIX, V11.1
January 2012 PTF for XL C/C++ for AIX, V11.1
April 2012 PTF for XL C for AIX, V11.1
April 2012 PTF for XL C/C++ for AIX, V11.1
July 2012 PTF for XL C/C++ for AIX, V11.1
October 2012 PTF for XL C for AIX, V11.1
October 2012 PTF for XL C/C++ for AIX, V11.1
February 2013 PTF for XL C for AIX, V11.1
February 2013 PTF for XL C/C++ for AIX, V11.1
XL C/C++ for AIX Fix Pack 14 (May 2013 PTF) for 11.1
XL C for AIX Fix Pack 14 (May 2013 PTF) for 11.1
XL C/C++ for AIX Fix Pack 15 (August 2013 PTF) for 11.1
XL C for AIX Fix Pack 15 (August 2013 PTF) for 11.1
XL C/C++ for AIX Fix Pack 16 (November 2013 PTF) for 11.1
XL C for AIX Fix Pack 17 (February 2014 PTF) for 11.1
XL C/C++ for AIX Fix Pack 17 (February 2014 PTF) for 11.1
XL C/C++ for AIX Fix Pack 18 (May 2014 PTF) for 11.1
XL C/C++ for AIX Fix Pack 19 (August 2014 PTF) for 11.1
XL C/C++ for AIX Fix Pack 20 (November 2014 PTF) for 11.1
XL C for AIX Fix Pack 21 (April 2015 PTF) for 11.1
XL C/C++ for AIX Fix Pack 21 (April 2015 PTF) for 11.1
XL C/C++ for AIX Fix Pack 22 (September 2015 PTF) for 11.1
XL C for AIX Fix Pack 23 (March 2016 PTF) for 11.1
XL C/C++ for AIX Fix Pack 23 (March 2016 PTF) for 11.1
XL C for AIX Fix Pack 24 (September 2016 PTF) for 11.1
XL C/C++ for AIX Fix Pack 24 (September 2016 PTF) for 11.1
August 2011 PTF for XL C for AIX, V11.1
November 2011 PTF for XL C for AIX, V11.1
July 2012 PTF for XL C for AIX, V11.1
XL C for AIX Fix Pack 16 (November 2013 PTF) for 11.1
XL C for AIX Fix Pack 18 (May 2014 PTF) for 11.1
XL C for AIX Fix Pack 19 (August 2014 PTF) for 11.1
XL C for AIX Fix Pack 20 (November 2014 PTF) for 11.1
XL C for AIX Fix Pack 22 (September 2015 PTF) for 11.1

Subscribe

You can track all active APARs for this component.

 

APAR status

  • Closed as program error.

Error description

  • When compiling at -O2, the test case takes the incorrect branch
    and results in an incorrect output at runtime.
    
    ===== TESTCASE:
    $cat tc.c
    #include <stdio.h>
    
    #include <string.h>
    #include <stdlib.h>
    
    #define FALSE 0
    #define TRUE  1
    
    typedef struct
    {
    #define OPTFLAGS_TMASK            7
    #define OPTFLAGS_TAND             1
    #define OPTFLAGS_TOR              2
    #define OPTFLAGS_TNOT             3
    
    #define OPTFLAGS_FFALSEFOUND      16 /*  If set, false
    subconditions were found  */
    #define OPTFLAGS_FTRUEFOUND       32 /*  If set, true
    subconditions were found  */
    #define OPTFLAGS_FNEGATED        256 /*  If set, we are in
    a negated (i. e. "not" branch)  */
        int Flags;
    
        const char *Node;
    }
    auxstackopteval_t;
    
    #define MAXOPTSDEPTH     200
    
    static int
    testroutine(const char *input, int mode)
    {
        auxstackopteval_t stack[MAXOPTSDEPTH];
        int istack, skipit;
    
        stack[0].Flags = OPTFLAGS_TAND; /*  top level node
    "<options>" is treated as "and"  */
        stack[0].Node = input;
        istack = 0;
    
        for(;;)
        {
            const char *xnode, *next;
            int type;
    
            /*printf("STACK #%d FL %d ND '%s'\n", istack,
    stack[istack].Flags, stack[istack].Node ?
              stack[istack].Node : "<NULL>");*/
    
            xnode = stack[istack].Node;
            if(xnode == NULL || *xnode == '\0' || *xnode == ':') /*
    pop  */
            {
                int oflags;
    
                if(istack == 0)
                    break;
    
                printf("stack[0].Flags = %d, stack[1].Flags =
    %d\n",stack[0].Flags, stack[1].Flags);
    
                /*  Here is where the problems starts: The new two
    lines seem to be executed in
                 *   the wrong order!
                 */
                oflags = stack[istack].Flags;
                --istack;
    
                /*  Merge result  */
                if((oflags & OPTFLAGS_TMASK) ==  OPTFLAGS_TAND) /*
    "and" - one failure sufficient  */
                {
                    stack[istack].Flags |= !(oflags &
    OPTFLAGS_FFALSEFOUND) ?
                        OPTFLAGS_FTRUEFOUND :  OPTFLAGS_FFALSEFOUND;
                }
                else if((oflags & OPTFLAGS_TMASK) ==  OPTFLAGS_TOR)
    /*  "or"  - one success is enough  */
                {
                    stack[istack].Flags |= (oflags &
    OPTFLAGS_FTRUEFOUND) ?
                        OPTFLAGS_FTRUEFOUND : OPTFLAGS_FFALSEFOUND;
                }
                else
                {
                    stack[istack].Flags |= (oflags &
    OPTFLAGS_FFALSEFOUND) ?
                        OPTFLAGS_FTRUEFOUND :  OPTFLAGS_FFALSEFOUND;
    /*  "not" - negate  */
                }
    
                if(oflags != stack[istack + 1].Flags)
                    printf("*** BUG!!! Should have read
    stack[%d].Flags = %d, but have %d\n", istack + 1,
                           stack[istack + 1].Flags, oflags);
                else
                    printf("*** OK Read stack[%d].Flags =
    %d.\n",istack + 1, stack[istack + 1].Flags);
    
                continue;
            }
    
            next = strchr(xnode, ':') + 1;
    
            if(*xnode == 'a')
            {
                type = OPTFLAGS_TAND;
            }
            else if(*xnode == 'o')
            {
                type = OPTFLAGS_TOR;
            }
            else if(*xnode == '!')
            {
                type = OPTFLAGS_TNOT;
            }
            else if(*xnode == '+' || *xnode == '-')
            {
                int flags, emode, condition;
    
                type = 0;
                flags = stack[istack].Flags;
    
                condition = *xnode == '+' ? 2 : 1;
    
                /*  Check if condition applies at all  */
                if(condition != 0)
                {
                    condition = condition == 2; /*  map to proper
    TRUE/FALSE  */
    
                    stack[istack].Flags |= condition ?
    OPTFLAGS_FTRUEFOUND : OPTFLAGS_FFALSEFOUND;
    
                    /*  Short circuit for "and" and "or"  */
                    if(!(mode & 8) &&
                       (flags & OPTFLAGS_TMASK) == (condition ?
    OPTFLAGS_TOR : OPTFLAGS_TAND))
                    {
                        /*  We can finish the loop since at least
    one is true (for "or")
                         *   or at least one is false (for "and").
                         */
                        next = NULL;
                    }
                }
            }
            else
            {
                fprintf(stderr, "Internal error: Invalid condition
    node '%s' - expect and/or/not/option", input);
                goto error;
            }
    
            /*  Advance on same level  */
            stack[istack].Node = next;
    
            if(type != 0)
            {
                int isneg;
    
                /* ***  push  *** */
                isneg = stack[istack].Flags & OPTFLAGS_FNEGATED;
                if(type == OPTFLAGS_TNOT)
                    isneg ^= OPTFLAGS_FNEGATED;
    
                ++istack;
                stack[istack].Flags = isneg | type;
                stack[istack].Node  = input + 1;
                continue;
            }
        }
    
        /*  Top level is "and" condition, so one false is enough to
    fail completely  */
        skipit = (stack[0].Flags & OPTFLAGS_FFALSEFOUND) ?
    TRUE : FALSE;
    
        return skipit;
    error:
        return -1;
    }
    
    int main(int argc, char *argv[])
    {
        int rc;
    
        rc = testroutine("o+-:", 0);
    
        printf("RC %d\n", rc);
        return 0;
    }
    $
    
    ===== ACTUAL OUTPUT:
    $ ./tc
    stack[0].Flags = 1, stack[1].Flags = 34
    *** BUG!!! Should have read stack[1].Flags = 34, but have 1
    RC 1
    
    ===== EXPECTED OUTPUT:
    $ ./tc
    stack[0].Flags = 1, stack[1].Flags = 34
    *** OK Read stack[1].Flags = 34.
    RC 0
    

Local fix

  • N/A
    

Problem summary

  • USERS AFFECTED:
    This is a pattern sensitive optimization defect. Some users
    that compile with optimization may encounter this problem.
    
    PROBLEM DESCRIPTION:
    A specific optimization function failed to invalidate an
    internal optimizer cache after a state change.
    

Problem conclusion

  • The optimization function has been fixed to validate the
    internal optimizer cache after a state change.
    

Temporary fix

Comments

APAR Information

  • APAR number

    IZ99244

  • Reported component name

    XL C FOR AIX

  • Reported component ID

    5724X1200

  • Reported release

    B10

  • Status

    CLOSED PER

  • PE

    NoPE

  • HIPER

    NoHIPER

  • Special Attention

    NoSpecatt

  • Submitted date

    2011-04-20

  • Closed date

    2011-04-20

  • Last modified date

    2011-12-01

  • APAR is sysrouted FROM one or more of the following:

    IZ94727

  • APAR is sysrouted TO one or more of the following:

Fix information

  • Fixed component name

    XL C FOR AIX

  • Fixed component ID

    5724X1200

Applicable component levels

[{"Line of Business":{"code":"LOB57","label":"Power"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SSGH2K","label":"XL C for AIX"},"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"11.1"}]

Document Information

Modified date:
06 October 2021