-
Type:
Bug
-
Resolution: Fixed
-
Priority:
High
-
Code Generation Tools
-
CODEGEN-16376
-
-
-
default
-
Apply `#pragma UNROLL(1)` to an affected loop. Alternatively, manually vectorize an affected loop.
In very rare cases, when the compiler vectorizes a reduction operation (such as an accumulation), part of the final reduction operation may not occur.
For example, in the following loop, the reductive operation += may not be completed, resulting in `s` incorrectly containing `0.0f` instead of the summed value:
float sumSqDev(const float *data, unsigned int n, float mean)
{
float s = 0.0f;
for (unsigned int i = 0; i < n; ++i) {
float d = data[i] - mean;
s += d * d;
}
return s;
}
If this bug occurs, the following comment will always be in assembly:
; Peeled loop iterations for unrolled loop:
If the above comment is not in assembly, the corresponding loop is not affected.
If this bug occurs, a VSEL instruction will be in assembly, near the assembly comment. If a VSEL instruction is not in assembly near the assembly comment, the corresponding loop is not affected.
If a loop that performs a reductive operation is affected, pragma UNROLL(1) may be used to avoid the bug:
float sumSqDev(const float *data, unsigned int n, float mean)
{
float s = 0.0f;
#pragma UNROLL(1)
for (unsigned int i = 0; i < n; ++i) {
float d = data[i] - mean;
s += d * d;
}
return s;
}
Only the following scalar reduction operations are affected by this bug. (Vector and complex types are not affected so hand-optimized code with vectors will be unaffected.):
- += with integer or floating point types
- &=, |=, ^= with integer types
- Min and max idioms (e.g. `a = a < b[i] ? a : b[i]`) with integer or floating point types.
This bug will not occur if the loop has a known (non-variable) trip count.
In summary, this bug may occur if:
- Source code uses an affected reduction operation.
- The compiler can vectorize the code.
- The trip count is unknown.
A loop may be checked for impact by looking for the following in close proximity in assembly:
- `; Peeled loop iterations for unrolled loop:`
- `VSEL`
And a potentially affected loop may avoid this bug entirely by:
- Manually vectorizing the loop
- Using `#pragma UNROLL(1)`