+
+ /* Improve handling of STRICT_LOW_PART if the current value is known
+ to be const0_rtx, then the low bits will be set to dest and higher
+ bits will remain zero. Used in code like:
+
+ {di:SI=0;clobber flags:CC;}
+ flags:CCNO=cmp(bx:SI,0)
+ strict_low_part(di:QI)=flags:CCNO<=0
+
+ where we can note both that di:QI=flags:CCNO<=0 and
+ also that because di:SI is known to be 0 and strict_low_part(di:QI)
+ preserves the upper bits that di:SI=zero_extend(flags:CCNO<=0). */
+ scalar_int_mode mode;
+ if (dest != orig
+ && cselib_record_sets_hook
+ && REG_P (dest)
+ && HARD_REGISTER_P (dest)
+ && sets[i].src_elt
+ && is_a <scalar_int_mode> (GET_MODE (dest), &mode)
+ && n_sets + n_strict_low_parts < MAX_SETS)
+ {
+ opt_scalar_int_mode wider_mode_iter;
+ FOR_EACH_WIDER_MODE (wider_mode_iter, mode)
+ {
+ scalar_int_mode wider_mode = wider_mode_iter.require ();
+ if (GET_MODE_PRECISION (wider_mode) > BITS_PER_WORD)
+ break;
+
+ rtx reg = gen_lowpart (wider_mode, dest);
+ if (!REG_P (reg))
+ break;
+
+ cselib_val *v = cselib_lookup (reg, wider_mode, 0, VOIDmode);
+ if (!v)
+ continue;
+
+ struct elt_loc_list *l;
+ for (l = v->locs; l; l = l->next)
+ if (l->loc == const0_rtx)
+ break;
+
+ if (!l)
+ continue;
+
+ sets[n_sets + n_strict_low_parts].dest = reg;
+ sets[n_sets + n_strict_low_parts].src = dest;
+ sets[n_sets + n_strict_low_parts++].src_elt = sets[i].src_elt;
+ break;
+ }
+ }