Re: Another code snippet that Sparse has problems with

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Sep 07, 2017 at 12:05:58AM +0100, Dibyendu Majumdar wrote:
> Hi,
> 
> I recently found another test case that fails:
> 
> static int test_do(void) {
>     int a = 0;
>     int count = 27;
>     switch (count % 8) {
>     case 0: do {  a++;
>     case 7:       a++;
>     case 6:       a++;
>     case 5:       a++;
>     case 4:       a++;
>     case 3:       a++;
>     case 2:       a++;
>     case 1:       a++;
>             } while ((count -= 8) > 0);
>     }
>     if (27 != a) return 1;
>     return 0;
> }


Ah, a Duff device with a constant. A smart compiler could
optimize it away entirely.

In our case, the simplification of the switch (called once
and with a constant value) leave all the case's phi-node
incorrect (but the one for 3).

The following patch should solve it but I would like to have a
better way to do the matching between the BB and the phi-operands.

With this I get the follwing result, which look correct:
	foo:
	.L0:
		<entry-point>
		phisrc.32   %phi13(a) <- $0
		phisrc.32   %phi21(count) <- $27
		br          .L7
	
	.L6:
		add.32      %r12 <- %r18, $5
		phisrc.32   %phi14(a) <- %r12
		phisrc.32   %phi32(count) <- %r21
		br          .L7
	
	.L7:
		phi.32      %r34(a) <- %phi13(a), %phi14(a)
		phi.32      %r37(count) <- %phi21(count), %phi32(count)
		add.32      %r18 <- %r34(a), $3
		add.32      %r21 <- %r37(count), $-8
		setgt.32    %r23 <- %r21, $0
		cbr         %r23, .L6, .L1
	
	.L1:
		setne.32    %r25 <- %r18, $27
		ret.32      %r25


------------------------------------------------------------------------

>From 275d1ae2c2e187783d1d095d5f9f5950bc360be9 Mon Sep 17 00:00:00 2001
From: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx>
Date: Thu, 7 Sep 2017 03:18:30 +0200
Subject: [PATCH] fix remove_parent()

---
 linearize.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 45 insertions(+), 1 deletion(-)

diff --git a/linearize.c b/linearize.c
index eabf8575a..eb6b53a0a 100644
--- a/linearize.c
+++ b/linearize.c
@@ -649,9 +649,53 @@ static void set_activeblock(struct entrypoint *ep, struct basic_block *bb)
 		add_bb(&ep->bbs, bb);
 }
 
+
+static void remove_nth_phisource(struct instruction *insn, int nth)
+{
+	pseudo_t src;
+	int i = 0;
+
+	FOR_EACH_PTR(insn->phi_list, src) {
+		if (++i < nth)
+			continue;
+		*THIS_ADDRESS(src) = VOID;
+		return;
+	} END_FOR_EACH_PTR(src);
+	assert(0);
+}
+
+static void remove_nth_phisources(struct basic_block *bb, int nth)
+{
+	struct instruction *insn;
+
+	FOR_EACH_PTR(bb->insns, insn) {
+		if (!insn->bb)
+			continue;
+		if (insn->opcode != OP_PHI)
+			break;
+
+		remove_nth_phisource(insn, nth);
+	} END_FOR_EACH_PTR(insn);
+}
+
 static void remove_parent(struct basic_block *child, struct basic_block *parent)
 {
-	remove_bb_from_list(&child->parents, parent, 1);
+	struct basic_block *bb;
+	int nth = 0;
+
+	FOR_EACH_PTR(child->parents, bb) {
+		nth++;
+
+		if (bb != parent)
+			continue;
+
+		DELETE_CURRENT_PTR(bb);
+		goto found;
+	} END_FOR_EACH_PTR(bb);
+	assert(0);	// should never be reached
+
+found:
+	remove_nth_phisources(child, nth);
 	if (!child->parents)
 		repeat_phase |= REPEAT_CFG_CLEANUP;
 }
-- 
2.14.0

--
To unsubscribe from this list: send the line "unsubscribe linux-sparse" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux