Fixes are available
XL C/C++ for AIX Fix Pack 6 (February 2016 PTF) for 13.1
XL C for AIX Fix Pack 6 (February 2016 Update) for 13.1
XL C for AIX Fix Pack 7 (May 2016 Update) for 13.1
XL C/C++ for AIX Fix Pack 7 (May 2016 PTF) for 13.1
XL C for AIX Fix Pack 8 (August 2016 Update) for 13.1
XL C/C++ for AIX Fix Pack 8 (August 2016 PTF) for 13.1
XL C for AIX Fix Pack 9 (June 2017 Update) for 13.1
XL C/C++ for AIX Fix Pack 9 (June 2017 PTF) for 13.1
XL C for AIX Fix Pack 10 (February 2018 Update) for 13.1
XL C/C++ for AIX Fix Pack 10 (February 2018 PTF) for 13.1
XL C/C++ for AIX Fix Pack 11 (November 2018 PTF) for 13.1
XL C for AIX Fix Pack 11 (November 2018) for 13.1
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 compile with IPA may be affected by this issue. PROBLEM DESCRIPTION: The IPA optimization was incorrectly optimizing away volatile variables due to incorrect information in an internal hash function.
Problem conclusion
The problem has been resolved.
Temporary fix
Comments
APAR Information
APAR number
IV81773
Reported component name
XL C FOR AIX
Reported component ID
5725C7100
Reported release
C10
Status
CLOSED PER
PE
NoPE
HIPER
NoHIPER
Special Attention
NoSpecatt / Xsystem
Submitted date
2016-02-24
Closed date
2016-02-24
Last modified date
2016-02-24
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
5725C7100
Applicable component levels
RD10 PSY
Document Information
Modified date:
04 October 2021