http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54017
Bug #: 54017 Summary: Incorrect implementation of infinite loops in OpenMP sections leads to SIGILL Classification: Unclassified Product: gcc Version: 4.7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassig...@gcc.gnu.org ReportedBy: il...@rz.rwth-aachen.de Consider this very simple OpenMP sections code: int main() { #pragma omp parallel sections { #pragma omp section { for(;1;) {} } } return 0; } Since there is only one OpenMP section, if this code is run with more than one thread, GOMP_sections_start() would return 0 in all but the first thread to call it. Unfortunately the compiler generates the following assembly code to test the return value: movl $1, %edi call GOMP_sections_start cmpl $1, %eax je .L4 .value 0x0b0f .L4: jmp .L4 In all threads but the first one the JE instruction would not branch and the UD2 instruction emitted by __builtin_trap() would get hit and the program will abort with SIGILL. Tested also with "for(;;) {}" and "while(1) {}" - same assembly code emitted. If instead the code of the section is modified to read: #pragma omp section { int i = 1; for(;i;) {} } the produced assembly code correctly handles 0 as the possible return value of GOMP_sections_next(): call GOMP_sections_next .L7: testl %eax, %eax je .L4 cmpl $1, %eax je .L5 .value 0x0b0f .L4: call GOMP_sections_end_nowait jmp .L8 .L5: movl $1, -4(%rbp) .L6: cmpl $0, -4(%rbp) jne .L6 call GOMP_sections_next jmp .L7 .L8: leave Also if at least one another section without infinite loop is added, e.g.: #pragma omp section { for(;1;) {} } #pragma omp section { int k = 5; } return value from GOMP_sections_next() is processed correctly: call GOMP_sections_next .L8: cmpl $1, %eax je .L6 cmpl $1, %eax jb .L5 cmpl $2, %eax je .L7 .value 0x0b0f .L5: call GOMP_sections_end_nowait jmp .L9 .L7: movl $5, -4(%rbp) call GOMP_sections_next jmp .L8 .L6: jmp .L6 .L9: leave The correct behaviour in the first case should be that other threads would wait infinitely at the barrier in GOMP_parallel_end() and not crash with SIGILL as in the first case. Unfortunately I don't have access to GCC versions higher than 4.7.0 but I've tested it with previous versions down to 4.3.4 with the same result. Optimisation level has no influence on the problem. It also fails in 32-bit mode.