/* { dg-do run } */ /* { dg-options "-O2 -msse4" } */ /* { dg-require-effective-target sse4} */ typedef unsigned short u16; typedef unsigned int u32; typedef unsigned char u8; u32 __attribute__((__force_align_arg_pointer__)) unreach(const u16 * pu16, u16 *dst, u32 dstlen, const u8 *src, u32 srclen) { for (u32 i = dstlen; srclen && i; i--, srclen--, src++, dst++) { u16 off = pu16[*src]; if (off) { src++; srclen--; *dst = pu16[off + *src]; } } return 56; } u32 __attribute__((__force_align_arg_pointer__)) __attribute__((noipa)) bug(const u16 * pu16, u16 *dst, u32 dstlen, const u8 *src, u32 srclen) { if (pu16) /* Branch should not execute, but stack realignment * reads wrong 'pu16' value from stack. */ return unreach(pu16, dst, dstlen, src, srclen); return (srclen < dstlen) ? srclen : dstlen; } int main() { if (__builtin_cpu_supports ("sse4.1")) { /* Should return 12 */ if (bug(0, 0, 12, 0, 34) != 12) __builtin_abort (); } return 0; }