This fork of the canonical git mirror of the LLVM subversion repository adds (e)Z80 targets. Please refer to the wiki for important build instructions.
It appears to be the narrow_icmp combiner at fault. lib/CodeGen/GlobalISel/CombinerHelper.cpp:4035 XORs together the known bits from LHS and RHS, in this case 0xF/0x0 with 0xFFFF9C/0x63, producing 0xC/0x3. It checks if all bits are zero - they're not. It checks if any bits are one: two bits are, and so it sets the result to an immediate value of 1.
This check is only correct for direct equality comparisons, not for inequalities like ugt.
I added a small guard before the XOR to work around the problem in my fork, but I'm not sure if this is a particularly good way to deal with the issue:
Hi again,
This short section of code is incorrectly generated:
With
-O0
the output never performs either the__iand
or the comparison. The relevant portion of the assembly output is:Obviously, this test always succeeds:
a
is set to 1..LBB0_2
branches to thereturn 1
.With
-O1
or better it merely saves time on the above constant computation:It looks like the known bits computation makes a bit of a blunder:
It appears to be the
narrow_icmp
combiner at fault.lib/CodeGen/GlobalISel/CombinerHelper.cpp:4035
XORs together the known bits from LHS and RHS, in this case 0xF/0x0 with 0xFFFF9C/0x63, producing 0xC/0x3. It checks if all bits are zero - they're not. It checks if any bits are one: two bits are, and so it sets the result to an immediate value of 1.This check is only correct for direct equality comparisons, not for inequalities like
ugt
.I added a small guard before the XOR to work around the problem in my fork, but I'm not sure if this is a particularly good way to deal with the issue: