diff options
Diffstat (limited to 'lib/test_bitmap.c')
| -rw-r--r-- | lib/test_bitmap.c | 68 | 
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/test_bitmap.c b/lib/test_bitmap.c index d5923a640457..98754ff9fe68 100644 --- a/lib/test_bitmap.c +++ b/lib/test_bitmap.c @@ -604,6 +604,12 @@ static void __init test_bitmap_arr64(void)  			pr_err("bitmap_copy_arr64(nbits == %d:"  				" tail is not safely cleared: %d\n", nbits, next_bit); +		if ((nbits % 64) && +		    (arr[(nbits - 1) / 64] & ~GENMASK_ULL((nbits - 1) % 64, 0))) +			pr_err("bitmap_to_arr64(nbits == %d): tail is not safely cleared: 0x%016llx (must be 0x%016llx)\n", +			       nbits, arr[(nbits - 1) / 64], +			       GENMASK_ULL((nbits - 1) % 64, 0)); +  		if (nbits < EXP1_IN_BITS - 64)  			expect_eq_uint(arr[DIV_ROUND_UP(nbits, 64)], 0xa5a5a5a5);  	} @@ -869,6 +875,67 @@ static void __init test_bitmap_print_buf(void)  	}  } +static void __init test_bitmap_const_eval(void) +{ +	DECLARE_BITMAP(bitmap, BITS_PER_LONG); +	unsigned long initvar = BIT(2); +	unsigned long bitopvar = 0; +	unsigned long var = 0; +	int res; + +	/* +	 * Compilers must be able to optimize all of those to compile-time +	 * constants on any supported optimization level (-O2, -Os) and any +	 * architecture. Otherwise, trigger a build bug. +	 * The whole function gets optimized out then, there's nothing to do +	 * in runtime. +	 */ + +	/* +	 * Equals to `unsigned long bitmap[1] = { GENMASK(6, 5), }`. +	 * Clang on s390 optimizes bitops at compile-time as intended, but at +	 * the same time stops treating @bitmap and @bitopvar as compile-time +	 * constants after regular test_bit() is executed, thus triggering the +	 * build bugs below. So, call const_test_bit() there directly until +	 * the compiler is fixed. +	 */ +	bitmap_clear(bitmap, 0, BITS_PER_LONG); +#if defined(__s390__) && defined(__clang__) +	if (!const_test_bit(7, bitmap)) +#else +	if (!test_bit(7, bitmap)) +#endif +		bitmap_set(bitmap, 5, 2); + +	/* Equals to `unsigned long bitopvar = BIT(20)` */ +	__change_bit(31, &bitopvar); +	bitmap_shift_right(&bitopvar, &bitopvar, 11, BITS_PER_LONG); + +	/* Equals to `unsigned long var = BIT(25)` */ +	var |= BIT(25); +	if (var & BIT(0)) +		var ^= GENMASK(9, 6); + +	/* __const_hweight<32|64>(GENMASK(6, 5)) == 2 */ +	res = bitmap_weight(bitmap, 20); +	BUILD_BUG_ON(!__builtin_constant_p(res)); +	BUILD_BUG_ON(res != 2); + +	/* !(BIT(31) & BIT(18)) == 1 */ +	res = !test_bit(18, &bitopvar); +	BUILD_BUG_ON(!__builtin_constant_p(res)); +	BUILD_BUG_ON(!res); + +	/* BIT(2) & GENMASK(14, 8) == 0 */ +	res = initvar & GENMASK(14, 8); +	BUILD_BUG_ON(!__builtin_constant_p(res)); +	BUILD_BUG_ON(res); + +	/* ~BIT(25) */ +	BUILD_BUG_ON(!__builtin_constant_p(~var)); +	BUILD_BUG_ON(~var != ~BIT(25)); +} +  static void __init selftest(void)  {  	test_zero_clear(); @@ -884,6 +951,7 @@ static void __init selftest(void)  	test_for_each_set_clump8();  	test_bitmap_cut();  	test_bitmap_print_buf(); +	test_bitmap_const_eval();  }  KSTM_MODULE_LOADERS(test_bitmap);  |