Fixes are available
APAR status
Closed as program error.
Error description
When optimization is enabled, xlc optimizes away a loop with volatile variable. OPT code of LOCK() [ the inner while loop is optimized away, although it contains volatile variable p_o4trc_header->who_pid] ie From: void LOCK(int my_pid) { int n=0, z=0, y=-1; do { z=0; while(p_o4trc_header->who_pid != 0 && z<1000000) z+=1; y++; } while ( _check_lock((int*)&p_o4trc_header->who_pid,n,my_pid) ); printf("inner loop count %d; outer loop count %d\n", z,y); return; } To: The Machne code behaves as a C code written like: void LOCK(int my_pid) { int n=0, z=0, y=-1; do { if( p_o4trc_header->who_pid != 0 ) z = 1000000 else z=0; y++; } while ( _check_lock((int*)&p_o4trc_header->who_pid,n,my_pid) ); printf("inner loop count %d; outer loop count %d\n", z,y); return; } 0x100000880 (LOCK(int)) fbe1fff8 std r31,-8(r1) $r31 = &p_o4trc_header; 0x100000884 (LOCK(int)+0x4) fbc1fff0 std r30,-16(r1) 0x100000888 (LOCK(int)+0x8) 3be0ffff li r31,-1 0x10000088c (LOCK(int)+0xc) 3c80000f lis r4,0xf 0x100000890 (LOCK(int)+0x10) 7c0802a6 mflr r0 0x100000894 (LOCK(int)+0x14) fba1ffe8 std r29,-24(r1) 0x100000898 (LOCK(int)+0x18) fb81ffe0 std r28,-32(r1) 0x10000089c (LOCK(int)+0x1c) fb61ffd8 std r27,-40(r1) 0x1000008a0 (LOCK(int)+0x20) 3bc2ff40 addi r30,-192(r2) 0x1000008a4 (LOCK(int)+0x24) 7c7d07b4 extsw r29,r3 $r29 = my_pid; 0x1000008a8 (LOCK(int)+0x28) 3b644240 addi r27,0x4240(r4) $r27 = 1000000; 0x1000008ac (LOCK(int)+0x2c) f8010010 std r0,0x10(r1) 0x1000008b0 (LOCK(int)+0x30) f821ff61 stdu r1,-160(r1) Store stack pointer 0x1000008b4 (LOCK(int)+0x34) 60000000 ori r0,r0,0x0 0x1000008b8 (LOCK(int)+0x38) 60000000 ori r0,r0,0x0 0x1000008bc (LOCK(int)+0x3c) 60210000 ori r1,r1,0x0 0x1000008c0 (LOCK(int)+0x40) e87e0000 |--> ld r3,0x0(r30) $r3 = p_o4trc_header; 0x1000008c4 (LOCK(int)+0x44) 3bff0001 | addi r31,0x1(r31) y = y +1; 0x1000008c8 (LOCK(int)+0x48) 38800000 | li r4,0x0 $r4 = 0; 0x1000008cc (LOCK(int)+0x4c) 63a50000 | ori r5,r29,0x0 $r5 = mypid; 0x1000008d0 (LOCK(int)+0x50) e8030002 | lwa r0,0x0(r3) $r0 = p_o4trc_header->who_pid; 0x1000008d4 (LOCK(int)+0x54) 7cc000d0 | neg r6,r0 ($r0 == 0) $r6 = 0 : $r6 = -$r0; 0x1000008d8 (LOCK(int)+0x58) 7c003378 | or r0,r0,r6 ($r0 == 0) $r0 = 0 : $r0 = negativ number; 0x1000008dc (LOCK(int)+0x5c) 7c06fe76 | sradi r6,r0,0x3f ($r0 < 0) $r6 = -1 : $r6 = 0; 0x1000008e0 (LOCK(int)+0x60) 7cdcd838 | and r28,r6,r27 if (p_o4trc_header->who_pid == 0) z = $r28 = 0; else z = $r28 = 1000000; 0x1000008e4 (LOCK(int)+0x64) 48003423 | bla 0x0000000000003420 _check_lock($r3=&p_o4trc_header->who_pid, $r4=0, $r5 = my_pid) 0x1000008e8 (LOCK(int)+0x68) 2c030000 | cmpi cr0,0x0,r3,0x0 0x1000008ec (LOCK(int)+0x6c) 4082ffd4 |<-- bne 0x1000008c0 (LOCK(int)+0x40 0x1000008f0 (LOCK(int)+0x70) 7fe507b4 extsw r5,r31 $r5 = y; 0x1000008f4 (LOCK(int)+0x74) e86200f0 ld r3,0xf0(r2) 0x1000008f8 (LOCK(int)+0x78) 63840000 ori r4,r28,0x0 $r4 = z; 0x1000008fc (LOCK(int)+0x7c) 48000305 bl 0x100000c00 (printf) 0x100000900 (LOCK(int)+0x80) e8410028 ld r2,0x28(r1) 0x100000904 (LOCK(int)+0x84) e98100b0 ld r12,0xb0(r1) 0x100000908 (LOCK(int)+0x88) 382100a0 addi r1,0xa0(r1) 0x10000090c (LOCK(int)+0x8c) 7d8803a6 mtlr r12 0x100000910 (LOCK(int)+0x90) eb61ffd8 ld r27,-40(r1) 0x100000914 (LOCK(int)+0x94) eb81ffe0 ld r28,-32(r1) 0x100000918 (LOCK(int)+0x98) eba1ffe8 ld r29,-24(r1) 0x10000091c (LOCK(int)+0x9c) ebc1fff0 ld r30,-16(r1) 0x100000920 (LOCK(int)+0xa0) ebe1fff8 ld r31,-8(r1) 0x100000924 (LOCK(int)+0xa4) 4e800020 blr =====Testcase: $ cat test.c #include <pthread.h> #include <sys/atomic_op.h> extern "C" void exit ( int s); #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/shm.h> #include <unistd.h> #pragma pack(1) typedef struct _o4trc_header_t { /* offset 0x00: * this is lock */ pid_t who_pid; /* this is data */ pid_t data_pid; } o4trc_header_t; #pragma pack(pop) static volatile o4trc_header_t* p_o4trc_header = 0; static void o4trc_shm ( void ) { int key, id = -1; bool created = false; key = 44444; // some key /* first, try to get existing shared memory.... */ id = shmget ( key, 1024, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); if ( id == -1 ) { /* no shared memory with this key exists, so we create it... */ errno = 0; id = shmget ( key, 1024, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | IPC_CREAT ); if ( id == -1 ) exit(-1); else created = true; } /* the shared memory already existed */ else created = false; /* attach to shared memory */ errno = 0; p_o4trc_header = (o4trc_header_t*) shmat ( id, NULL, 0 ); if ( ! p_o4trc_header ) exit(-1); /* init if needed */ if ( created ) { /* initialize with default values */ p_o4trc_header->data_pid = 0; _clear_lock((int*)&p_o4trc_header->who_pid, 0); } return; } /* o4trc_shm */ void LOCK(int my_pid) { int n=0, z=0, y=-1; do { z=0; while(p_o4trc_header->who_pid != 0 && z<1000000) z+=1; y++; } while ( _check_lock((int*)&p_o4trc_header->who_pid,n,my_pid) ); printf("inner loop count %d; outer loop count %d\n", z,y); return; } void RELEASE(void) { _clear_lock((int*)&p_o4trc_header->who_pid, 0); return; } // erst ohne Parameter aufrufen, dann 1 Sekunde später mit einem dummy parameter aufrufen int main (int argc, char** argv) { pid_t my_pid = getpid (), lock_pid, check_pid; int n,x, y, z=0; // get shared memory if (!p_o4trc_header) o4trc_shm(); if (!p_o4trc_header) return 1; LOCK(my_pid); RELEASE(); return 0; } $ ===== COMPILE COMMAND: xlC_r -+ -g -D_AIX51 -D_LARGE_FILES -U__unix -q64 -qtbtable=full -qhalt=e -qalias=noansi -qutf -qcpluscmt -qfdpr -qstrict -qlibansi -qinlglue -qmaxmem=-1 -DNDEBUG -qarch=pwr4 -qtune=balanced -qspill=2560 -qsaveopt -O -qipa=relink:level=0:partition=large -r -qdebug=ndf_bc -qlonglong -qalign=natural -qldbl128 -qlanglvl=extc89 -c -o test.o test.c
Local fix
N/A
Problem summary
USERS AFFECTED: Users who make use of IPA on AIX are potentially affected by this issue. PROBLEM DESCRIPTION: Volatile variables are optimized away incorrectly by the compiler.
Problem conclusion
The compiler has been fixed.
Temporary fix
Comments
APAR Information
APAR number
IV78407
Reported component name
XL C/C++ FOR AI
Reported component ID
5725C7200
Reported release
B10
Status
CLOSED PER
PE
NoPE
HIPER
NoHIPER
Special Attention
NoSpecatt / Xsystem
Submitted date
2015-10-29
Closed date
2016-03-28
Last modified date
2016-03-28
APAR is sysrouted FROM one or more of the following:
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
RB10 PSY
UP
[{"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SSGH2K","label":"XL C for AIX"},"Component":"","ARM Category":[],"Platform":[{"code":"PF025","label":"Platform Independent"}],"Version":"11.1","Edition":"","Line of Business":{"code":"LOB57","label":"Power"}}]
Document Information
Modified date:
28 March 2016