https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103383
--- Comment #11 from Álvaro "G. M." <alvaro.gamez at hazent dot com> ---
(In reply to Álvaro "G. M." from comment #10)
> Created attachment 62778 [details]
> Patch against 15.2.0 to solve this issue
Hi,
Just wanted to confirm that this bug still exists on gcc-15.2.0
I discovered it because compiling Linux for a microblaze CPU was leaving me
with a functional system but in which I didn't have IP connectivity: not even
ping to localhost. After quite a journey, I discovered that the culprit was in
calls to htons next to a condition. One of them was this function:
static void inline iph_set_totlen(struct iphdr *iph, unsigned int len)
{
iph->tot_len = (len <= 0xFFFFU) ? htons(len) : 0;
}
Which, when inlined in this function:
int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
{
struct iphdr *iph = ip_hdr(skb);
IP_INC_STATS(net, IPSTATS_MIB_OUTREQUESTS);
my_iph_set_totlen(iph, skb->len);
ip_send_check(iph);
/* if egress device is enslaved to an L3 master device pass the
* skb to its handler for processing
*/
skb = l3mdev_ip_out(sk, skb);
if (unlikely(!skb))
return 0;
skb->protocol = htons(ETH_P_IP);
return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
net, sk, skb, NULL, skb_dst_dev(skb),
dst_output);
}
will produce code like this:
lwi r4,r19,80
addik r5,r0,65535
cmpu r18,r4,r5
bgeid r18,$L608
swapb r3, r4
swaph r3, r3
addk r3,r0,r0
$L608:
addk r5,r22,r0
But when not inlined, it would produce this:
my_iph_set_totlen:
.frame r1,0,r15 # vars= 0, regs= 0, args= 0
.mask 0x00000000
addik r4,r0,65535
cmpu r18,r6,r4
bltid r18,$L59
addk r3,r0,r0
swapb r3, r6
swaph r3, r3
$L59:
rtsd r15,8
shi r3,r5,2
.end my_iph_set_totlen
The change from bltid to bgeid will produce that opposite of what is intended,
instead of assigning the value of htons(len), it would effectively set the
variable to 0.
Applying the patch provided by Andrew Pinski in comment #2 solved the issue and
I got kernel kernel 6.12 to work perfectly (as for now) with the full IP stack:
> I think this patch fixes the problem:
> diff --git a/gcc/config/microblaze/microblaze.md
> b/gcc/config/microblaze/microblaze.md
> index 6d77752cbfd..ca4bd976a5c 100644
> --- a/gcc/config/microblaze/microblaze.md
> +++ b/gcc/config/microblaze/microblaze.md
> @@ -372,7 +372,8 @@ (define_insn "bswaphi2"
> "TARGET_REORDER"
> "swapb %0, %1
> swaph %0, %0"
> -)
> + [(set_attr "length" "8")
> + (set_attr "type" "no_delay_arith")])
>
> ;;----------------------------------------------------------------
> ;; Microblaze delay slot description
>
>
If I need to rebase this patch against an specific commit or branch to have
this merged upstream, please let me know.
Thanks