Open
Description
The GVN optimizes-out the pointer-check code in else block of the below code snippet as part of 'removing nonlocal load' instruction. This is incorrect, because the pointer is getting modified in setjmp() part at first time, the bar() may do longjmp with second argument value other than zero. Moreover, the pointer itself marked as volatile too. So GVN shouldn't propagate top-level null value assignment to else block. Also saw that GVN works fine if I pass '-enable-gvn-memdep=false' to disable memdep of GVN pass.
This problem doesn't exist in gcc compiler. The link to ce is here https://godbolt.org/z/M7jh4fYdo
#include <stdio.h>
#include <setjmp.h>
extern int bar(void**);
typedef struct aFlag {
int flg;
} aFlag;
extern jmp_buf buf;
void foo() {
volatile void *kPtr = ((void*)0);
static int trace = 0;
if(setjmp(buf) == 0) {
bar((void **)&kPtr);
} else {
trace++;
if (kPtr != ((void*)0)) // This code is getting removed in GVN pass
((aFlag *)kPtr)->flg |= 0x0001;
}
printf("trace: %d\n", trace);
}