2009-05-07 Jakub Jelinek <jakub@redhat.com> PR middle-end/40057 * dojump.c (prefer_and_bit_test): Use immed_double_const instead of GEN_INT for 1 << bitnum. (do_jump) <case BIT_AND_EXPR>: Use build_int_cstu instead of build_int_cst_type if TYPE_PRECISION (argtype) is bigger than HOST_BITS_PER_WIDE_INT. * gcc.c-torture/execute/pr40057.c: New test. --- gcc/dojump.c.jj 2009-04-24 21:41:28.000000000 +0200 +++ gcc/dojump.c 2009-05-07 14:54:05.000000000 +0200 @@ -140,7 +140,8 @@ prefer_and_bit_test (enum machine_mode m } /* Fill in the integers. */ - XEXP (and_test, 1) = GEN_INT ((unsigned HOST_WIDE_INT) 1 << bitnum); + XEXP (and_test, 1) + = immed_double_const ((unsigned HOST_WIDE_INT) 1 << bitnum, 0, mode); XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum); return (rtx_cost (and_test, IF_THEN_ELSE) @@ -250,10 +251,15 @@ do_jump (tree exp, rtx if_false_label, r && prefer_and_bit_test (TYPE_MODE (argtype), TREE_INT_CST_LOW (shift))) { - HOST_WIDE_INT mask = (HOST_WIDE_INT) 1 - << TREE_INT_CST_LOW (shift); - do_jump (build2 (BIT_AND_EXPR, argtype, arg, - build_int_cst_type (argtype, mask)), + unsigned HOST_WIDE_INT mask + = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift); + tree maskt; + + if (TYPE_PRECISION (argtype) <= HOST_BITS_PER_WIDE_INT) + maskt = build_int_cst_type (argtype, mask); + else + maskt = build_int_cstu (argtype, mask); + do_jump (build2 (BIT_AND_EXPR, argtype, arg, maskt), clr_label, set_label); break; } --- gcc/testsuite/gcc.c-torture/execute/pr40057.c.jj 2009-05-07 15:07:59.000000000 +0200 +++ gcc/testsuite/gcc.c-torture/execute/pr40057.c 2009-05-07 15:05:54.000000000 +0200 @@ -0,0 +1,37 @@ +/* PR middle-end/40057 */ + +extern void abort (void); + +__attribute__((noinline)) int +foo (unsigned long long x) +{ + unsigned long long y = (x >> 31ULL) & 1ULL; + if (y == 0ULL) + return 0; + return -1; +} + +__attribute__((noinline)) int +bar (long long x) +{ + long long y = (x >> 31LL) & 1LL; + if (y == 0LL) + return 0; + return -1; +} + +int +main (void) +{ + if (sizeof (long long) != 8) + return 0; + if (foo (0x1682a9aaaULL)) + abort (); + if (!foo (0x1882a9aaaULL)) + abort (); + if (bar (0x1682a9aaaLL)) + abort (); + if (!bar (0x1882a9aaaLL)) + abort (); + return 0; +}