I am missing something: a == 0 iff popcnt(a) == 0, so indeed a == 0 || b == 0 is equivalent to popcnt(a) == 0 || popcnt(b) == 0 which can be written as !(popcnt(a) && popcnt(b)), but if this is translated into a single-branch sequence of machine instructions, then wouldn’t !(a && b) be as well?
The solution I was thinking of by counting leading zero bits is (with LZCNT said instruction, | bitwise or, ~ bitwise not, >> logical shift right, and 32 = 2^5 bit integers): LZCNT(a) >> 5 | LZCNT(b) >> 5 Using POPCNT in the same way is also possible: POPCNT(~a) >> 5 | POPCNT(~b) >> 5 Cheers, Louis > On 28 Jul 2019, at 23:49, Roger Hui <[email protected]> wrote: > > If you have thought about this for a year then the following can't be the > answer, but here it is: > > There is either a popcnt instruction, or you can implement it with > straight-line code without branching. Whence: > if !(popcnt(a)&&popcnt(b)) stmt; > > > >> On Sun, Jul 28, 2019 at 5:51 PM Henry Rich <[email protected]> wrote: >> >> Many of the members of this Forum will remember the days of assembler >> language >> >> ...and who could less than merry be >> when writing out BXLE? >> >> AND, OR, XOR were our meat. Those days are returning. >> >> You have two integer variables a and b and you want to do something if >> one or both of them are 0. In C, you might write >> >> if(a==0 || b==0)stmt; >> >> but that will generate the code >> >> cmp a,0 >> bz stmt >> cmp b,0 >> bnz notstmt >> stmt: >> ... >> notstmt: >> >> Here's the problem: your machine is very slow at branch instructions. >> Each branch takes 30 times as long as a regular instruction. (I am >> describing a state-of-the-art Intel CPU when it cannot predict the >> branches effectively, perhaps because the data is... unpredictable). >> >> Obviously, you want to use only one branch instruction. You may use as >> many arithmetic and logic instructions as you like, but only one >> branch. The usual condition codes, ZNCV, are available. How tight can >> you make the code? >> >> Example: suppose the problem were to execute stmt if one or both of a >> and b is NOT zero. Then you would simply write >> >> or a,b >> bnz notstmt >> ... >> >> Checking for zero seems to be harder. >> >> No hurry. I have pondered this problem for over a year, and just today >> I found a solution I consider acceptable. >> >> Henry Rich >> >> >> >> >> >> >> >> --- >> This email has been checked for viruses by AVG. >> https://www.avg.com >> >> ---------------------------------------------------------------------- >> For information about J forums see http://www.jsoftware.com/forums.htm >> > ---------------------------------------------------------------------- > For information about J forums see http://www.jsoftware.com/forums.htm ---------------------------------------------------------------------- For information about J forums see http://www.jsoftware.com/forums.htm
