IBM Support

IV78407: XLC OPTIMIZES AWAY LOOP WITH VOLATILE VARIABLE

Subscribe

You can track all active APARs for this component.

 

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&#228;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:

    IV78575

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