constant propagation produces undef

I’m sure I’m missing something in my port for PIC16 because the following code produces undef for pic16 but it is ok for other ports but I’m not sure what is it that I’m missing.

Looks like the constant propagation pass finds out that f() is always returning 16 and it tries to substitute the call site in the shift with statement 16. But since int is 16 bit it results in undef in the input of check() function while zero is expected.

If I modify f() to return 15 I will get the correct code.

I was wondering if someone can give me a clue as what is it that I’m missing.

By the way, this problem is happening on clang with optimizations on (-O1). Without optimizations, things work fine.

extern int k; //int is 16 bit

extern int C;

int f(void)

{

return 16;

}

void check(int );

int main (void)

{

k = 1;

C = k << f();

check (C);

return 0;

}

Produces :

@k = external global i16 ; <i16*> [#uses=1]

define i16 @f() nounwind readnone {

entry:

ret i16 16

}

define i16 @main() nounwind {

entry:

store i16 1, i16* @k

tail call void @check(i16 undef) nounwind

ret i16 0

}

Thanks

Ali

If int is 16 bits, 1<<16 is undefined, not zero. If you want a "safe"
shift, try defining something like the following:

static inline int safe_shift(int a, int b) {
  return b>=16?0:a<<b;
}

-Eli

For us all undefined values are zero, I tried it on ARM and X86 also and
clang generates zero, and not an undefined.

Maybe the better question would be "how can I tell clang to replace all
undefined values with zero constant?"

Thanks
A.

For us all undefined values are zero, I tried it on ARM and X86 also and
clang generates zero, and not an undefined.

That is because on x86 and arm, int -> i32. This produces undef on x86:

int test() {
int x = 1;
return x << 32;
}

Maybe the better question would be "how can I tell clang to replace all
undefined values with zero constant?"

You can't, that's not how C works. If you build with the -fcatch-undefined-behavior option, it should catch this error at runtime.

-Chris

Thanks,
I fixed it in the backend.

A.