341-riscv64-u32-register-narrow.c (1251B)
1 /* A 64-bit expression narrowed to unsigned int must discard bits 63:32 2 * even when it stays in a register. RISC-V comparisons operate on the 3 * full XLEN register, so stale upper bits otherwise make an immediately 4 * following unsigned relational comparison use the pre-cast u64 value. 5 * 6 * Keep the value behind a call: local lvalues are loaded with LW and do 7 * not exercise the unspilled-register path. */ 8 typedef unsigned int u32; 9 typedef unsigned long u64; 10 11 static u64 ident(u64 x) 12 { 13 return x; 14 } 15 16 int main(void) 17 { 18 u32 one = 1; 19 20 if (!((u32)ident(0x1234567800000000UL) < 1U)) 21 return 1; 22 if ((u32)ident(0x1234567800000000UL) >= one) 23 return 2; 24 if (!((u32)ident(0x1234567800000000UL) < 25 (u32)ident(0xabcdef0100000001UL))) 26 return 3; 27 28 if ((u32)ident(0x12345678ffffffffUL) != 0xffffffffU) 29 return 4; 30 if ((u64)(u32)ident(0x12345678ffffffffUL) != 0xffffffffUL) 31 return 5; 32 if ((u32)ident(0x1234567880000000UL) != 0x80000000U) 33 return 6; 34 if ((u64)(u32)ident(0x1234567880000000UL) != 0x80000000UL) 35 return 7; 36 if (!((int)ident(0x1234567800000000UL) < 1)) 37 return 8; 38 if ((int)ident(0x12345678ffffffffUL) != -1) 39 return 9; 40 41 return 0; 42 }