(compare (subreg:QI (plus (reg:SI) (-1))) (-3))
into: (compare (plus (reg:SI) (-1)) (-3))But I don't believe this transformation (lifting the subreg) is valid for this particular instance. Here are the more explicit rtl dumps - before:
(insn 14 12 15 0 (set (reg:SI 104) (plus:SI (reg:SI 103 [ <variable>.uc8 ])(const_int -1 [0xffffffff]))) 4 {*arm_addsi3} (insn_list:REG_DEP_TRUE 12 (nil))
(expr_list:REG_DEAD (reg:SI 103 [ <variable>.uc8 ]) (nil))) (insn 15 14 16 0 (set (reg:SI 105) (and:SI (reg:SI 104)(const_int 255 [0xff]))) 53 {*arm_andsi3_insn} (insn_list:REG_DEP_TRUE 14 (nil))
(expr_list:REG_DEAD (reg:SI 104) (nil))) (insn 16 15 17 0 (set (reg:CC 24 cc) (compare:CC (reg:SI 105)(const_int 253 [0xfd]))) 194 {*arm_cmpsi_insn} (insn_list:REG_DEP_TRUE 15 (nil))
(expr_list:REG_DEAD (reg:SI 105) (nil))) After: (note 14 12 15 0 NOTE_INSN_DELETED) (insn 15 14 16 0 (set (reg:SI 105) (plus:SI (reg:SI 103 [ <variable>.uc8 ])(const_int -1 [0xffffffff]))) 4 {*arm_addsi3} (insn_list:REG_DEP_TRUE 12 (nil))
(expr_list:REG_DEAD (reg:SI 103 [ <variable>.uc8 ]) (nil))) (insn 16 15 17 0 (set (reg:CC 24 cc) (compare:CC (reg:SI 105)(const_int -3 [0xfffffffd]))) 194 {*arm_cmpsi_insn} (insn_list:REG_DEP_TRUE 15 (nil))
(expr_list:REG_DEAD (reg:SI 105) (nil)))The conversion is being done at the "case SUBREG" code starting around line 10191 of combine.c. The conversion is allowed because the following tests are met:
((unsigned HOST_WIDE_INT) c1 < (unsigned HOST_WIDE_INT) 1 << (mode_width - 2) /* (A - C1) always sign-extends, like C2. */ && num_sign_bit_copies (a, inner_mode) > (unsigned int) (GET_MODE_BITSIZE (inner_mode) - mode_width - 1)) In my case: c1 is 3, which is less than 1 << 6, andnum_sign_bit_copies(a,SI) is 24 (because the SI register "a" contains a zero-extended QI value), and
"GET_MODE_BITSIZE (inner_mode) - mode_width - 1" is 23Now, as I understand things, we're trying to see if "compare (subreg (a - c1), c2)" is the same as "compare (a - c1, c2)". And, this is considered acceptable if the result of "a - c1" is identical to a sign extended "subreg (a - c1)". So far, so good. However, as I apply the code to the SI/QI subreg case reads:
if (INTVAL (c1) < 64) and there are at least 24 identical bits at the top of a
This logic, however, doesn't seem to match. First, it would seem there should be at least 25 identical bits to verify that we do indeed have a sign-extended QI value. But even with that addressed, consider another case (again with the QI/SI for concreteness). Suppose we have an expression like:
lt (subreg (a - 1), -3)And, suppose for this example that "a" is a SI sign-extended from a signed QI. So, num_sign_bit_copies would be 25. The transformation would be allowed (because c1 is less than 64 and num_sign_bit_copies is greater than 24). However, if "a" contained a value of -128 at run-time:
lt (subreg (a - 1), -3) becomes lt (subreg (-129), -3) becomes lt (127), -3 == FALSE whereas after the transformation: lt (a - 1, -3) becomes lt (-129, -3) == TRUEAm I misinterpreting the logic? Am I missing something fundamental? I appreciate any feedback / pointers / clues / etc...
- Josh
test.c
Description: Binary data