Bitmasks for constants are currently created only for trailing zeros.
There is no reason not to also include leading 1's in the value that are
also known.
Given a range such as [5,7], possible values in binary are 00000101,
00000110, 00000111. we can conclude that not only are the leading 5
bits 0, but we can also be sure that the next bit is a 1.
The calculation to include the 1's is actually slightly faster than
excluding them. This also helps with various bit comparisons.
before : [5, 7] mask 0x7 value 0x0 // first 5 bits are known to
be 00000
after : [5, 7] mask 0x3 value 0x4 // first 6 bits are known to
be 000001
Bootstraps on x86_64-pc-linux-gnu with no regressions. Pushed.
Andrew
From 65cd212bd4c533351a09e6974f40ae5d7effca84 Mon Sep 17 00:00:00 2001
From: Andrew MacLeod <amacl...@redhat.com>
Date: Wed, 14 May 2025 11:12:22 -0400
Subject: [PATCH 2/4] Improve constant bitmasks.
bitmasks for constants are created only for trailing zeros. It is no
additional work to also include leading 1's in the value that are also
known.
before : [5, 7] mask 0x7 value 0x0
after : [5, 7] mask 0x3 value 0x4
PR tree-optimization/116546
* value-range.cc (irange_bitmask::irange_bitmask): Include
leading ones in the bitmask.
---
gcc/value-range.cc | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/gcc/value-range.cc b/gcc/value-range.cc
index 48a1521b81e..64d10f41168 100644
--- a/gcc/value-range.cc
+++ b/gcc/value-range.cc
@@ -47,9 +47,11 @@ irange_bitmask::irange_bitmask (tree type,
else
{
wide_int xorv = min ^ max;
- xorv = wi::mask (prec - wi::clz (xorv), false, prec);
- m_value = wi::zero (prec);
- m_mask = min | xorv;
+ // Mask will have leading zeros for all leading bits that are
+ // common, both zeros and ones.
+ m_mask = wi::mask (prec - wi::clz (xorv), false, prec);
+ // Now set value to those bits which are known, and zero the rest.
+ m_value = ~m_mask & min;
}
}
--
2.45.0