Fixes are available
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 $ cat tc.c #include <stdio.h> #include <string.h> #include <stdlib.h> #define FALSE 0 #define TRUE 1 typedef struct { #define SAPUP_OPTFLAGS_TMASK 7 #define SAPUP_OPTFLAGS_TAND 1 #define SAPUP_OPTFLAGS_TOR 2 #define SAPUP_OPTFLAGS_TNOT 3 #define SAPUP_OPTFLAGS_FFALSEFOUND 16 /* If set, false subconditions were found */ #define SAPUP_OPTFLAGS_FTRUEFOUND 32 /* If set, true subconditions were found */ #define SAPUP_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 = SAPUP_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 & SAPUP_OPTFLAGS_TMASK) == SAPUP_OPTFLAGS_TAND) /* "and" - one failure sufficient */ { stack[istack].Flags |= !(oflags & SAPUP_OPTFLAGS_FFALSEFOUND) ? SAPUP_OPTFLAGS_FTRUEFOUND : SAPUP_OPTFLAGS_FFALSEFOUND; } else if((oflags & SAPUP_OPTFLAGS_TMASK) == SAPUP_OPTFLAGS_TOR) /* "or" - one success is enough */ { stack[istack].Flags |= (oflags & SAPUP_OPTFLAGS_FTRUEFOUND) ? SAPUP_OPTFLAGS_FTRUEFOUND : SAPUP_OPTFLAGS_FFALSEFOUND; } else { stack[istack].Flags |= (oflags & SAPUP_OPTFLAGS_FFALSEFOUND) ? SAPUP_OPTFLAGS_FTRUEFOUND : SAPUP_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 = SAPUP_OPTFLAGS_TAND; } else if(*xnode == 'o') { type = SAPUP_OPTFLAGS_TOR; } else if(*xnode == '!') { type = SAPUP_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 ? SAPUP_OPTFLAGS_FTRUEFOUND : SAPUP_OPTFLAGS_FFALSEFOUND; /* Short circuit for "and" and "or" */ if(!(mode & 8) && (flags & SAPUP_OPTFLAGS_TMASK) == (condition ? SAPUP_OPTFLAGS_TOR : SAPUP_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 & SAPUP_OPTFLAGS_FNEGATED; if(type == SAPUP_OPTFLAGS_TNOT) isneg ^= SAPUP_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 & SAPUP_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
IZ94727
Reported component name
XLC C++ AIX
Reported component ID
5724M1200
Reported release
800
Status
CLOSED PER
PE
NoPE
HIPER
NoHIPER
Special Attention
NoSpecatt
Submitted date
2011-02-08
Closed date
2011-05-11
Last modified date
2011-05-12
APAR is sysrouted FROM one or more of the following:
APAR is sysrouted TO one or more of the following:
IZ97865 IZ99244 LI76125 LI76210 LI76230 IV02125 LI76372 LI76390
Fix information
Fixed component name
XLC AIX
Fixed component ID
5724M1100
Applicable component levels
[{"Line of Business":{"code":"LOB08","label":"Cognitive Systems"},"Business Unit":{"code":"BU054","label":"Systems w\/TPS"},"Product":{"code":"SSJT9L","label":"XL C\/C++"},"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"8.0"}]
Document Information
Modified date:
07 October 2021