http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52408
Bug #: 52408 Summary: Incorrect assembler generated for zvdep_imm64 Classification: Unclassified Product: gcc Version: 4.6.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: target AssignedTo: unassig...@gcc.gnu.org ReportedBy: dang...@gcc.gnu.org Host: hppa64-*-* Target: hppa64-*-* Build: hppa64-*-* The following testcase is miscompiled at -O1: typedef unsigned long long loff_t; typedef unsigned long long blkcnt_t; typedef unsigned long long u64; #define MAX_LFS_FILESIZE 0x7fffffffffffffffULL loff_t ext4_max_size(int blkbits, int has_huge_files) { loff_t res; loff_t upper_limit = MAX_LFS_FILESIZE; if (!has_huge_files || sizeof(blkcnt_t) < sizeof(u64)) { upper_limit = (1LL << 32) - 1; upper_limit >>= (blkbits - 9); upper_limit <<= blkbits; } res = (1LL << 32) - 1; res <<= blkbits; if (res > upper_limit) res = upper_limit; return res; } int main(void) { printf("res = 0x%lx\n", ext4_max_size(12, 0)); return 0; } Wrong code is generated for the "res <<= blkbits;" operation. We have the following rtl: (insn 27 26 65 (set (reg/v:DI 31 %r31 [orig:71 res ] [71]) (ashift:DI (const_int 4294967295 [0xffffffff]) (minus:DI (const_int 63 [0x3f]) (reg:DI 60 SAR [82])))) ext4.c:21 230 {zvdep_imm64} (expr_list:REG_DEAD (reg:DI 60 SAR [82]) (expr_list:REG_EQUAL (ashift:DI (const_int 4294967295 [0xffffffff]) (reg/v:DI 31 %r31 [orig:75 blkbits+-4 ] [75])) (nil)))) The pattern for zvdep_imm64 is: (define_insn "zvdep_imm64" [(set (match_operand:DI 0 "register_operand" "=r") (ashift:DI (match_operand:DI 1 "lhs_lshift_cint_operand" "") (minus:DI (const_int 63) (match_operand:DI 2 "register_operand" "q"))))] "TARGET_64BIT" "* { int x = INTVAL (operands[1]); operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1)); operands[1] = GEN_INT ((x & 0x1f) - 0x20); return \"depdi,z %1,%%sar,%2,%0\"; }" [(set_attr "type" "shift") (set_attr "length" "4")]) The lhs_lshift_cint_operand predicate allows the unsigned long long value 0xffffffff, but it is truncated when assigned to x. As a result, the call to exact_log2 fails and returns -1. This results in the following incorrect instruction: depdi,z -1,%sar,3,%r31 There appear to be a few more instances with the same problem... The problem has been present for years and affects all active versions.