Skip to content

Inconsistent Output at -O1 and -O2 Optimization Levels on PowerPC64 Due to Complex Type Casting and Nested Loop Structure #71030

@gyuminb

Description

@gyuminb

Description:

The Proof-of-Concept (PoC) code provided demonstrates an inconsistency in the computed results of an unsigned long long int variable when compiled using Clang-18 for the PowerPC64 architecture. The discrepancy is observed specifically under the optimization levels -O1 and -O2. The output of computedResultUll displays inconsistency as shown below:

Computed Result (ULL): ffffffffffffffff
Computed Result (ULL): ffffffff
Computed Result (ULL): ffffffff
Computed Result (ULL): ffffffffffffffff

Environment:

  • Compiler: Clang-18
  • Target Architecture: PowerPC64
  • Optimization Level: This issue is exclusively observed at O1 and O2 optimization levels.

PoC:

#include <stdio.h>

// Define a macro to find the minimum value between two numbers
#define MIN(a,b) \
    ({ __typeof__ (a) _a = (a); \
       __typeof__ (b) _b = (b); \
       _a < _b ? _a : _b; })

// Global variables
short globalShortValue = (short)1;
signed char globalCharValue = (signed char)0;
unsigned long long largeNumber = 14782061517590169264ULL;
int someIntValue = 378441747;
unsigned int unitIncrement = 1U;

// Variables to store the results of computations
unsigned long long computedResultUll = 0ULL;
short computedResultShort = (short)0;
unsigned char computedResultUChar = (unsigned char)0;
_Bool computedResultBool = (_Bool)0;
unsigned char computedResultChar = (unsigned char)0;

// Arrays used in computations
short shortArray[8];
long long int longArray[8][8];
int intArray[8][8][8];
unsigned long long ullArray[8];
signed char charArray[8][8][8];
short resultArray[8][8];

// Initialize arrays
void initializeArrays() {
    for (size_t i = 0; i < 8; ++i) {
        shortArray[i] = (short)-1;
        ullArray[i] = 1;
        for (size_t j = 0; j < 8; ++j) {
            longArray[i][j] = 0LL;
            resultArray[i][j] = (short)1;
            for (size_t k = 0; k < 8; ++k) {
                intArray[i][j][k] = 0;
                charArray[i][j][k] = (signed char)0;
            }
        }
    }
}

int main() {
    initializeArrays();
    // Main loop for computations
    for (short index = 3; index < ((int) (short) largeNumber) - 1705/*7*/; index += 4) {
        computedResultUll = (unsigned long long) ((int) MIN(globalShortValue, shortArray[index])); // Potential issue here
        for (int i = 0; i < 8; i++) {
            for (signed char j = ((int) (signed char) someIntValue) - 19/*0*/; j < 8; j += 4) {
                for (long long int k = 2; k < 4; k += 4) {
                    computedResultShort -= (short) unitIncrement;
                    computedResultUChar = (unsigned char) (_Bool) MIN((short) globalCharValue, shortArray[index - 1]);
                    charArray[2][0][index] = (signed char) globalShortValue;
                    resultArray[0][0] &= (short) longArray[0][j];
                }
                for (int l = 1; l < 7; l++) {
                    computedResultBool = (_Bool) (ullArray[index]);
                    computedResultChar -= (unsigned char) intArray[0][index][j];
                }
            }
        }
    }
    // Print the result
    printf("Computed Result (ULL): %llx\n", computedResultUll);
}

Expected Behavior:

Regardless of the optimization level, the value of computedResultUll should be consistently and accurately computed as an unsigned long long int.

Observed Behavior:

When compiled with Clang-18 under -O1 and -O2 optimization levels, the computed value for computedResultUll shows inconsistency:

Computed Result (ULL): ffffffffffffffff
Computed Result (ULL): ffffffff
Computed Result (ULL): ffffffff
Computed Result (ULL): ffffffffffffffff

Analysis:

The inconsistency is identified under the following conditions:

  1. Nested Loops and Type Casting: The issue is seen in a complex nested loop structure where boundary conditions involve type casting.
  2. Array Operations: The presence of operations involving multiple arrays seems to be a contributing factor.
  3. Unsigned Type Extension: The primary concern appears to be an incorrect extension of a value to unsigned long long int.

These conditions are specific and intricate, but the inconsistency is notable and is not attributed to Undefined Behavior.

Steps to Reproduce:

  1. Compile the PoC code using Clang-18 targeting PowerPC64 with O1 and O2 optimization levels.
  2. Run the compiled binary.
  3. Observe the inconsistency in the output for computedResultUll.

Conclusion:

The observed inconsistency in extending values to unsigned long long int, under specific conditions involving complex loop structures and type casting operations, when compiled using Clang-18 at -O1 and -O2 optimization levels, warrants further investigation and resolution.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions