https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93231
--- Comment #4 from Wilco <wilco at gcc dot gnu.org> --- (In reply to Jakub Jelinek from comment #0) > int ctz2 (int x) > { > static const char table[32] = > { > 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, > 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 > }; > > return table[((int)((x & -x) * -0x077CB531)) >> 27]; > } > > ICEs because > unsigned HOST_WIDE_INT val = tree_to_uhwi (mulc); > is used without checking that the INTEGER_CST fits into uhwi. > If we don't want to support signed x, we should start the function by > verification that inner_type is INTEGRAL_TYPE_P which is TYPE_UNSIGNED, if > we do want to support even signed values, it needs to be tweaked differently. I guess TREE_INT_CST_LOW should fix that. The goal is to support signed and unsigned types. > Similarly, > int ctz3 (unsigned x) > { > static const char table[32] = > { > 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, > 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 > }; > > return table[((unsigned)((x & -x) * 0x077CB531U)) >> -27]; > } > ICEs because -27 doesn't fit into uhwi. We should just punt if it doesn't. I'm adding an extra tree_fits_uhwi for that. > I'm also surprised by > /* Check the array is not wider than integer type and the input is a 32-bit > or 64-bit type. */ > if (TYPE_PRECISION (type) > 32) > return false; > because the comment doesn't match what the check is doing, either you want > an array with 32-bit or smaller elts, then the comment should match that, or > you care about integers and then you should compare against TYPE_PRECISION > (integer_type_node). I'll check but I think this check is no longer required. > Also, there is no testcase for the string case, nor any non-target specific > testcase that it at least compiles and perhaps with tree dump scan on > selected > targets that it recognizes the ctz. I can add a generic testcase as well. > And I don't see a check that if it is a STRING_CST, the array elements must > be > bytes and not wider, which the function assumes (e.g. if it is u"..."[(x & > -x) > * ...) >> 27]). Right now "abc"[] can't match - the constructor always returns an error for this case. And this doesn't seem a common idiom so adding support isn't useful.