Skip to content

Commit

Permalink
[OpenMP] [Flang] Resolved Issue #76121: Implemented Check for Unhandl…
Browse files Browse the repository at this point in the history
…ed Arguments in __kmpc_fork_call_if (#82221)

Root cause: Segmentation fault is caused by null pointer dereference
inside the __kmpc_fork_call_if function at
https://github.com/llvm/llvm-project/blob/main/openmp/runtime/src/z_Linux_asm.S#L1186
. __kmpc_fork_call_if is missing case to handle argc=0 .

Fix: Added a check inside the __kmp_invoke_microtask function to handle
the case when argc is 0.

---------

Co-authored-by: Singh <chasingh@amd.com>
  • Loading branch information
chandankds and Singh authored May 9, 2024
1 parent 666970c commit 2a57657
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
4 changes: 4 additions & 0 deletions openmp/runtime/src/z_Linux_asm.S
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,9 @@ KMP_LABEL(kmp_invoke_pass_parms): // put 1st - 6th parms to pkfn in registers.
movq %rdi, %rbx // pkfn -> %rbx
leaq __gtid(%rbp), %rdi // &gtid -> %rdi (store 1st parm to pkfn)
leaq __tid(%rbp), %rsi // &tid -> %rsi (store 2nd parm to pkfn)
// Check if argc is 0
cmpq $0, %rax
je KMP_LABEL(kmp_no_args) // Jump ahead

movq %r8, %r11 // p_argv -> %r11

Expand Down Expand Up @@ -1195,6 +1198,7 @@ KMP_LABEL(kmp_1_exit):
cmovnsq (%r11), %rdx // p_argv[0] -> %rdx (store 3rd parm to pkfn)
#endif // KMP_MIC

KMP_LABEL(kmp_no_args):
call *%rbx // call (*pkfn)();
movq $1, %rax // move 1 into return register;

Expand Down
36 changes: 36 additions & 0 deletions openmp/runtime/test/misc_bugs/omp__kmpc_fork_call_if.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// RUN: %libomp-compile && %t | FileCheck %s

#include <stdio.h>
#include <omp.h>

typedef int32_t kmp_int32;
typedef void *ident_t;
typedef void *kmpc_micro;

#ifdef __cplusplus
extern "C" {
#endif
extern void __kmpc_fork_call_if(ident_t *loc, kmp_int32 argc,
kmpc_micro microtask, kmp_int32 cond,
void *args);
#ifdef __cplusplus
}
#endif

// Microtask function for parallel region
void microtask(int *global_tid, int *bound_tid) {
// CHECK: PASS
if (omp_in_parallel()) {
printf("FAIL\n");
} else {
printf("PASS\n");
}
}

int main() {
// Condition for parallelization (false in this case)
int cond = 0;
// Call __kmpc_fork_call_if
__kmpc_fork_call_if(NULL, 0, microtask, cond, NULL);
return 0;
}

0 comments on commit 2a57657

Please sign in to comment.