Post Go back to editing

Bug in Sharc C/C++ compiler

Category: Choose a category
Product Number: ADSP-SC584
Software Version: CCES 2.10.0

Please forgive me if my explanation is not crystal clear, English is not my first language.

I found a probable bug in cc21k compiler regarding DAG length register handling. Take the following C *code as a example:

#include <sys/platform.h>
#include <sys/adi_core.h>
#include "Bug_Test_Core1.h"
#include <stdio.h>

int Buffer[128];
int *Buffer_Ptr1 = Buffer;
int *Buffer_Ptr2 = Buffer + 10;

void Func1(int *data)
{
	printf("%d\n", *data);
}

void Func2(void)
{
	int signal = 0;
	int phase;
	int *res = NULL;

	int *ptr = Buffer_Ptr1;

	while(ptr != Buffer_Ptr2) {
		ptr = __builtin_circptr(ptr, sizeof(int), Buffer, sizeof(Buffer));

		if(!res || *ptr > *res)
			res = ptr;
	}

	Func1(res);
}

int main(void)
{
	Func2();

	return 0;
}

Func2's while loop uses DAG4 for circular buffer. Looking at the assembly produced by the compiler:

Func2.:
.LNFunc2.:
//-------------------------------------------------------------------
//  Procedure statistics:
//  Frame size            = 16 bytes
//  Scratch registers used: {r0-r2,r4,r12,i4,i12,b4,acc,scc}
//  Call preserved registers used: {i5,l4}
//  Registers that could be clobbered by function calls: {r0-r1,r4,r8,r12,s0-s15,i4,i6-i7,i12-i13,b4,b12-b13,m4,m12,ustat1-ustat4,acc,mcc,scc,btf,sacc,smcc,sscc,sbtf,stky,stkyy,mrf,mrb,msf,msb,lcntr,px}
//-------------------------------------------------------------------
// line "..\src\Bug_Test_Core1.c":16
	modify(i7,-2) (nw);
	r4=r4-r4, r2=i5;
	dm(-2,i6)=r2;
.LN4:
// line 21
	r2=dm(Buffer_Ptr1.);
.LN5:
// line 23
	r1=dm(Buffer_Ptr2.);
	comp(r2,r1), i5=r4;
	if eq jump (pc,.P39L2);

	b4=Buffer.;
	i4=r2;
	l4=128;
	r2=leftz r4;

.P39L3:
//-------------------------------------------------------------------
//   Loop at "..\src\Bug_Test_Core1.c" line 23 col 2
//-------------------------------------------------------------------
.LN6:
// line 26
	if sv jump (pc,.P39L4) (db);
.LN7:
// line 24
	modify(i4,m6) (nw);
	r2=i4;

.LN8:
// line 26
	r0=dm(i4,m5);
	r12=dm(i5,m5);
	comp(r12,r0);
	if ge jump (pc,.P39L8);

.P39L4:
	r4=i4;

.P39L8:
.LN9:
// line 23
	comp(r1,r2);
	if ne jump (pc,.P39L3) (db);
	r2=leftz r4, i5=r4;
	nop;
//-------------------------------------------------------------------
//   End Loop L3
//-------------------------------------------------------------------

//-------------------------------------------------------------------
//   Part of top level (no loop)
//-------------------------------------------------------------------

.P39L2:
.LN10:
// line 30
	cjump Func1. (db);
	dm(i7,m7)=r2;
	dm(i7,m7)=.LCJ1-1;
.LCJ1:

.LN11:
// line 31
	i12=dm(m7,i6);
	// -- 6 stalls --
	jump (m14,i12) (db);
	i5=dm(-2,i6);
	rframe;
.LN.Func2..end:
.Func2..end:
	.global Func2.;
	.type Func2.,STT_FUNC;

the L4 register is set to 128 (line 25), but never set back to 0. If you break the C code at line 12 or 37, the L4 register is set to 128 instead of 0 as it should be.

Am I missing some detail or is this a bug in the compiler?

Bug_Test_Core1.zip



Added sample project.
[edited by: GTBosco at 1:20 PM (GMT -4) on 26 Sep 2022]