Hi In function combine.c:make_compound_operation, it tries to transforms the expression (ashiftrt (ashift foo C1) C2) with C2 >= C1 into SIGN_EXTRACT.
It works pretty well in usual cases. But for the test case in PR49799, there is an expression (X << (tmp-1)) >> 16 tmp is an uninitialized variable, only after init-regs pass, it is set to 0. Then after several successful combine, it will see following expression (ashiftrt:SI (ashift:SI (reg:SI 145 [ *K_2(D) ]) (const_int -1 [0xffffffffffffffff])) (const_int 16 [0x10])) and change it to an illegal bit field extraction instruction(sbfx). Add a check to ensure the bit field is valid before applying the change, so the wrong sbfx will not be generated. Bootstrapped and regtested on x86_64-unknown-linux-gnu. Regtested on arm qemu. OK for trunk and 4.6? thanks Carrot ChangeLog: 2011-07-28 Wei Guozhi <car...@google.com> PR rtl-optimization/49799 * combine.c (make_compound_operation): Check if the bit field is valid before change it to bit field extraction. Index: gcc/combine.c =================================================================== --- gcc/combine.c (revision 176733) +++ gcc/combine.c (working copy) @@ -7787,6 +7787,7 @@ make_compound_operation (rtx x, enum rtx && GET_CODE (lhs) == ASHIFT && CONST_INT_P (XEXP (lhs, 1)) && INTVAL (rhs) >= INTVAL (XEXP (lhs, 1)) + && INTVAL (XEXP (lhs, 1)) >= 0 && INTVAL (rhs) < mode_width) { new_rtx = make_compound_operation (XEXP (lhs, 0), next_code);