These changes cover the PR#31399.
Now the ffs(x) function is lowered to (x != 0) ? llvm.cttz(x) + 1 : 0
and it corresponds to the following llvm code:
%cnt = tail call i32 @llvm.cttz.i32(i32 %v, i1 true) %tobool = icmp eq i32 %v, 0 %.op = add nuw nsw i32 %cnt, 1 %add = select i1 %tobool, i32 0, i32 %.op
and x86 asm code:
bsfl %edi, %ecx addl $1, %ecx testl %edi, %edi movl $0, %eax cmovnel %ecx, %eax
In this case the 'test' instruction can't be eliminated because
the 'add' instruction modifies the EFLAGS, namely, ZF flag
that is set by the 'bsf' instruction when 'x' is zero.
I have moved the 'add' instruction below the 'cmov' instruction
at the peephole optimization stage during the compare instruction
optimization (optimizeCompareInstr), i.e., to implement
the following transformation:
bsfl %edi, %ecx addl $1, %ecx --------* c1 = 1 testl %edi, %edi | movl $0, %eax * c2 = 0 -> c2 = c2 - c1 = -1 * transform to movl $-1, %eax cmovnel %ecx, %eax | <--------|
It produces the following code:
bsfl %edi, %ecx movl $-1, %eax cmovnel %ecx, %eax addl $1, %eax
You already checked that it was definitely a constant above. So you shouldn't need a dyn_cast here.
Or you should just check the CC in the first if, then select your Add and your possible constant. And check that it is an Add and a constant.