-
Notifications
You must be signed in to change notification settings - Fork 14.8k
Description
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
andO2
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:
- Nested Loops and Type Casting: The issue is seen in a complex nested loop structure where boundary conditions involve type casting.
- Array Operations: The presence of operations involving multiple arrays seems to be a contributing factor.
- 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:
- Compile the PoC code using Clang-18 targeting PowerPC64 with
O1
andO2
optimization levels. - Run the compiled binary.
- 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.