Bug 23980 - [3.4 Regression] THUMB basic block reordering incorrectly redirects non-simple cond-jump->fallthru
Summary: [3.4 Regression] THUMB basic block reordering incorrectly redirects non-simpl...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 3.4.4
: P2 normal
Target Milestone: 4.0.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-09-20 16:15 UTC by Chris Zimman
Modified: 2006-03-09 00:33 UTC (History)
2 users (show)

See Also:
Host:
Target: arm-elf-gcc
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-10-07 15:57:01


Attachments
mmcsd.s (18.23 KB, text/plain)
2005-10-07 14:53 UTC, Chris Zimman
Details
mmcsd.i (17.64 KB, text/plain)
2005-10-07 15:54 UTC, Chris Zimman
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Zimman 2005-09-20 16:15:32 UTC
Note, this problem only happens with -thumb and -O2 (eg. nothing, -O, -O1 and -
O3 work fine).

Here's the original snippet of code:

int 
mmcsd_read(void * dst, void * src, unsigned int len)
{
    int return_val = NETI_OK;
    int i = 0;

    cyg_mutex_lock(&mmcsd.mutex);
    
    if(!mmcsd.card_initialized) {
	cyg_mutex_unlock(&mmcsd.mutex);
	NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n",
(unsigned int) src, len);
	return NETI_MMCSD_CARD_UNINITIALIZED;
    }
     
    MMCSD_REG_SET_BIT(MMCSD_INT_MASK, MMCSD_INT_MASK_AUTO_CARD_DETECT);

    disconnect_card_detect_pullup();
  
    if(!len) {
	cyg_mutex_unlock(&mmcsd.mutex);

	NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returning len = 0\n",
(unsigned int) src, len);
	
	return NETI_OK;
    }
    if((((unsigned int)src)/MMCSD_BLOCK_LENGTH + len/MMCSD_BLOCK_LENGTH) > 
mmcsd.device_size) {
	cyg_mutex_unlock(&mmcsd.mutex);
	
	NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n",
(unsigned int) src, len);
   
	return NETI_MMCSD_INVALID_CARD_ADDRESS;
    }
    
    if(len % MMCSD_BLOCK_LENGTH) {
	cyg_mutex_unlock(&mmcsd.mutex);
	
	NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n",
(unsigned int) src, len);
	
	return NETI_MMCSD_INVALID_CARD_ADDRESS;
    }
    
    if(((unsigned int)src) % MMCSD_BLOCK_LENGTH) {
	cyg_mutex_unlock(&mmcsd.mutex);
	
	NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n",
(unsigned int) src, len);
	
	return NETI_MMCSD_INVALID_CARD_ADDRESS;
    }

    if((return_val = mmcsd_dma_read_blks(dst, (unsigned int) src, 
len/MMCSD_BLOCK_LENGTH)) != NETI_OK) {
	cyg_mutex_unlock(&mmcsd.mutex);
	
	NETI_DEBUG_PRINT_CONT("mmcsd_read(buf, 0x%x, %d) returnign error\n",
(unsigned int) src, len);
   
	return return_val;
    }
    
    connect_card_detect_pullup();   
    MMCSD_REG_CLEAR_BIT(MMCSD_INT_MASK,
			MMCSD_INT_MASK_AUTO_CARD_DETECT);
    
    cyg_mutex_unlock(&mmcsd.mutex);
   
    return return_val;
}

Here's the output from;

arm-elf-gcc -S -Wall -Wa,--gstabs -g -O2 -mcpu=arm920t ... -o mmcsd.s -c mmcsd.c

mmcsd_read:
.LFB59:
	.loc 1 1953 0
	push	{r4, r5, r6, r7, lr}
.LCFI33:
	mov	r7, fp
	mov	r6, sl
	mov	r5, r9
	mov	r4, r8
	push	{r4, r5, r6, r7}
.LCFI34:
	.loc 1 1957 0
	ldr	r4, .L623
	.loc 1 1953 0
	mov	fp, r0
	.loc 1 1957 0
	mov	r0, r4
	.loc 1 1953 0
	mov	r7, r2
	mov	r6, r1
	.loc 1 1957 0
	bl	cyg_mutex_lock
	.loc 1 1960 0
	mov	r2, #116
	neg	r2, r2
	add	r2, r2, r4
	ldr	r3, [r2, #112]
	mov	r8, r2
	cmp	r3, #0
	bne	.LCB2871
	b	.L615	@long jump
.LCB2871:
.LBB133:
	.loc 1 1972 0
	ldr	r3, .L623+4
.LBE133:
	mov	r1, #64
	ldr	r2, [r3]
	orr	r2, r2, r1
	str	r2, [r3]
	.loc 1 1975 0
	bl	disconnect_card_detect_pullup
	.loc 1 1977 0
	cmp	r7, #0
	beq	.L616
	.loc 1 1984 0
	lsr	r3, r7, #9
	mov	r5, r8
	mov	sl, r3
	lsr	r2, r6, #9
	ldr	r3, [r5, #68]
	add	r2, r2, sl
	cmp	r2, r3
	bls	.LCB2893
	b	.L611	@long jump
.LCB2893:
	.loc 1 1992 0
	ldr	r3, .L623+8
	tst	r7, r3
	beq	.LCB2898
	b	.L611	@long jump
.LCB2898:
	.loc 1 2000 0
	tst	r6, r3
	beq	.LCB2902
	b	.L611	@long jump
.LCB2902:
.LBB134:
.LBB135:
	.loc 1 1376 0
	ldr	r3, [r5, #92]
	cmp	r3, #0
	bne	.L583
	mov	r4, #23
.L610:
.LBE135:
.LBE134:
	.loc 1 2010 0
	ldr	r0, .L623
	bl	cyg_mutex_unlock
	.loc 1 2012 0
	ldr	r0, .L623+12
	mov	r1, r6
	mov	r2, r7
	bl	printf
	.loc 1 2014 0
	mov	r0, r4
.L573:
	.loc 1 2040 0
	@ sp needed for prologue
	pop	{r3, r4, r5, r6}
	mov	r8, r3
	mov	r9, r4
	mov	sl, r5
	mov	fp, r6
	pop	{r4, r5, r6, r7}
	pop	{r1}
	bx	r1
.L616:
	.loc 1 1978 0
	mov	r0, r4
	bl	cyg_mutex_unlock
	.loc 1 1980 0
	ldr	r0, .L623+16
	mov	r1, r6
	mov	r2, #0
	bl	printf
	.loc 1 2039 0
	mov	r0, #0
	b	.L573
.L583:
.LBB136:
.LBB137:
	.loc 1 1379 0
	mov	r0, #128
	lsl	r0, r0, #2
	mov	r1, sl
	bl	mmcsd_setup_transfer
	cmp	r0, #0
	mov	r9, r0
	beq	.L617
.L602:
	.loc 1 1503 0
	mov	r4, r9
.LBE137:
.LBE136:
	.loc 1 1371 0
	cmp	r4, #0
	bne	.L610
	.loc 1 2031 0
	bl	connect_card_detect_pullup
.LBB138:
	.loc 1 2032 0
	ldr	r3, .L623+4
.LBE138:
	mov	r1, #64
	ldr	r2, [r3]
	.loc 1 2035 0
	ldr	r0, .L623
	.loc 1 2032 0
	bic	r2, r2, r1
	str	r2, [r3]
	.loc 1 2035 0
	bl	cyg_mutex_unlock
	.loc 1 2039 0
	mov	r0, #0
	b	.L573
.L617:
.LBB139:
.LBB140:
	.loc 1 1383 0
	mov	r1, #1
	ldr	r0, [r5, #56]
	bl	dma_channel_set_operation
	.loc 1 1386 0
	ldr	r1, .L623+20
	mov	r2, #0
	ldr	r0, [r5, #56]
	bl	dma_channel_set_source_addr
	.loc 1 1389 0
	mov	r1, fp
	mov	r2, #1
	ldr	r0, [r5, #56]
	bl	dma_channel_set_dest_addr
	.loc 1 1392 0
	mov	r2, sl
	ldr	r0, [r5, #56]
	lsl	r1, r2, #9
	bl	dma_channel_set_count_reg
	.loc 1 1394 0
	ldr	r3, [r5, #84]
	cmp	r3, #0
	bne	.L618
	.loc 1 1421 0
	mov	r2, r8
	ldr	r0, [r2, #56]
	mov	r1, #16
	bl	dma_channel_set_burst_length
	.loc 1 1424 0
	mov	r3, sl
	cmp	r3, #1
	beq	.L619
	.loc 1 1436 0
	lsl	r2, r6, #16
	mov	r0, #18
	lsr	r1, r6, #16
	lsr	r2, r2, #16
	mov	r3, #9
	bl	mmcsd_send_cmd_wait_resp
	cmp	r0, #0
	mov	r9, r0
	bne	.L602
.L591:
	.loc 1 1451 0
	ldr	r2, .L623+4
	mov	r3, #2
	neg	r3, r3
	str	r3, [r2]
	.loc 1 1458 0
	bl	dma_cache_sync
	.loc 1 1462 0
	ldr	r4, .L623+24
	ldr	r1, .L623+28
	ldr	r0, [r4, #56]
	bl	dma_channel_set_control_register
	.loc 1 1474 0
	mov	r0, r4
	add	r0, r0, #60
	bl	cyg_semaphore_wait
	.loc 1 1479 0
	bl	dma_cache_sync
	.loc 1 1484 0
	mov	r0, r4
	add	r0, r0, #48
	bl	cyg_semaphore_wait
	.loc 1 1489 0
	ldr	r3, .L623+32
	ldr	r1, [r3]
	mov	r3, #47
	tst	r1, r3
	bne	.L600
	lsl	r2, r1, #20
	bmi	.L599
.L600:
	.loc 1 1491 0
	ldr	r3, .L623+36
	ldr	r3, [r3]
	cmp	r3, #0
	bne	.L620
	mov	r4, #24
	b	.L610
.L615:
.LBE140:
.LBE139:
	.loc 1 1961 0
	mov	r0, r4
	bl	cyg_mutex_unlock
	.loc 1 1962 0
	ldr	r0, .L623+12
	mov	r1, r6
	mov	r2, r7
	bl	printf
	.loc 1 1963 0
	mov	r0, #27
	b	.L573
.L618:
.LBB141:
.LBB142:
	.loc 1 1396 0
	ldr	r0, [r5, #56]
	mov	r1, #0
	bl	dma_channel_set_burst_length
	.loc 1 1398 0
	mov	r3, sl
	cmp	r3, #1
	beq	.L621
	.loc 1 1409 0
	lsl	r2, r6, #16
	mov	r0, #18
.L613:
	ldr	r3, .L623+40
	lsr	r1, r6, #16
	lsr	r2, r2, #16
.L614:
	.loc 1 1426 0
	bl	mmcsd_send_cmd_wait_resp
	cmp	r0, #0
	mov	r9, r0
	beq	.L591
	b	.L602
.L620:
	.loc 1 1491 0
	ldr	r0, .L623+44
	bl	printf
	mov	r4, #24
	b	.L610
.L611:
.LBE142:
.LBE141:
	.loc 1 2001 0
	mov	r0, r4
	bl	cyg_mutex_unlock
	.loc 1 2003 0
	ldr	r0, .L623+12
	mov	r1, r6
	mov	r2, r7
	bl	printf
	.loc 1 2005 0
	mov	r0, #26
	b	.L573
.L621:
.LBB143:
.LBB144:
	.loc 1 1399 0
	lsl	r2, r6, #16
	mov	r0, #17
	b	.L613
.L619:
	.loc 1 1426 0
	lsl	r2, r6, #16
	mov	r0, #17
	lsr	r1, r6, #16
	lsr	r2, r2, #16
	mov	r3, #9
	b	.L614
.L599:
	.loc 1 1496 0
	mov	r3, sl
	cmp	r3, #1
	bhi	.LCB3173
	b	.L602	@long jump
.LCB3173:
	.loc 1 1497 0
	mov	r0, #12
	mov	r1, #0
	mov	r2, #0
	mov	r3, #1
	bl	mmcsd_send_cmd_wait_resp
	cmp	r0, #0
	mov	r9, r0
	beq	.LCB3181
	b	.L622	@long jump
.LCB3181:
	b	.L602
.L624:
	.align	2
.L623:
	.word	mmcsd+116
	.word	-1610530780
	.word	511
	.word	.LC105
	.word	.LC107
	.word	2179128
	.word	mmcsd
	.word	2089
	.word	mmcsd_status_reg
	.word	neti_debug
	.word	521
	.word	.LC101
.LBE144:
.LBE143:
.LFE59:
	.size	mmcsd_read, .-mmcsd_read
	.section	.text.mmcsd_erase,"ax",%progbits
	.align	2
	.global	mmcsd_erase
	.code 16
	.thumb_func
	.type	mmcsd_erase, %function
Comment 1 Andrew Pinski 2005-09-20 16:21:02 UTC
can you provide the preprocessed source?

And does -W -Wall give any warnings?
Comment 2 Chris Zimman 2005-09-20 17:25:29 UTC
-Wall gives a warning about i not being used, but that's it.  We normally 
always build with -Wall enabled.

Here's the preprocessed output:

int
mmcsd_read(void * dst, void * src, unsigned int len)
{
    int return_val = NETI_OK;
    int i = 0;

    cyg_mutex_lock(&mmcsd.mutex);

    if(!mmcsd.card_initialized) {
 cyg_mutex_unlock(&mmcsd.mutex);
 printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len);
 return NETI_MMCSD_CARD_UNINITIALIZED;
    }

    *((volatile CYG_WORD32 *)(({ CYG_ADDRWORD _p = (CYG_ADDRWORD)(0x00214000 + 
0x24); if (_p >= 0x12000000 && _p < (0x12000000 +0x00400000)) _p = (_p & 
(0x00400000 -1)) + 0x00000000; else if (_p >= 0x00200000 && _p < (0x00200000 
+0x00100000)) _p = (_p & (0x00100000 -1)) + 0xA0000000; _p; }))) |= ((1 << 6));

    disconnect_card_detect_pullup();

    if(!len) {
 cyg_mutex_unlock(&mmcsd.mutex);

 printf("mmcsd_read(buf, 0x%x, %d) returning len = 0\n",(unsigned int) src, 
len);

 return NETI_OK;
    }
    if((((unsigned int)src)/512 + len/512) > mmcsd.device_size) {
 cyg_mutex_unlock(&mmcsd.mutex);

 printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len);

 return NETI_MMCSD_INVALID_CARD_ADDRESS;
    }

    if(len % 512) {
 cyg_mutex_unlock(&mmcsd.mutex);

 printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len);

 return NETI_MMCSD_INVALID_CARD_ADDRESS;
    }

    if(((unsigned int)src) % 512) {
 cyg_mutex_unlock(&mmcsd.mutex);

 printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len);

 return NETI_MMCSD_INVALID_CARD_ADDRESS;
    }

    if((return_val = mmcsd_dma_read_blks(dst, (unsigned int) src, len/512)) != 
NETI_OK) {
 cyg_mutex_unlock(&mmcsd.mutex);

 printf("mmcsd_read(buf, 0x%x, %d) returnign error\n",(unsigned int) src, len);

 return return_val;
    }

    connect_card_detect_pullup();
    *((volatile CYG_WORD32 *)(({ CYG_ADDRWORD _p = (CYG_ADDRWORD)(0x00214000 + 
0x24); if (_p >= 0x12000000 && _p < (0x12000000 +0x00400000)) _p = (_p & 
(0x00400000 -1)) + 0x00000000; else if (_p >= 0x00200000 && _p < (0x00200000 
+0x00100000)) _p = (_p & (0x00100000 -1)) + 0xA0000000; _p; }))) = *((volatile 
CYG_WORD32 *)(({ CYG_ADDRWORD _p = (CYG_ADDRWORD)(0x00214000 + 0x24); if (_p >= 
0x12000000 && _p < (0x12000000 +0x00400000)) _p = (_p & (0x00400000 -1)) + 
0x00000000; else if (_p >= 0x00200000 && _p < (0x00200000 +0x00100000)) _p = 
(_p & (0x00100000 -1)) + 0xA0000000; _p; }))) & ~((1 << 6));

    cyg_mutex_unlock(&mmcsd.mutex);

    return return_val;
}
Comment 3 Richard Earnshaw 2005-09-30 09:20:52 UTC
Please send the entire pre-processed file, not just a fragment of it.  Use the
'create a new attachment' link on the bugzilla page (see URL below).

You are also going to have to explain what you think is wrong with the currently
generated assembly file.  I can't tell from the information you've provided what
you think is wrong.
Comment 4 Chris Zimman 2005-10-07 14:53:51 UTC
Created attachment 9927 [details]
mmcsd.s

What happens is that a bogus label (.L622) gets created, and is treated as an unresolved symbol at link time.

Please find mmcsd.s (arm-elf-objdump -D mmcsd.o) attached.

If you still need the entire pre-processed source, I can attach that as well.
Comment 5 Richard Earnshaw 2005-10-07 15:51:08 UTC
Yes we need the preprocessed source code.  Unless I can run the compiler under a debugger there's no chance of working out what's going wrong.
Comment 6 Chris Zimman 2005-10-07 15:54:58 UTC
Created attachment 9928 [details]
mmcsd.i

This is the pre-processed output
Comment 7 Richard Earnshaw 2005-10-07 17:10:01 UTC
The problem here is that we have a complex compare-and-jump insn with side effects, so the insn can't be simply removed.  cfgrtl is getting confused and is generating code that references a deleted label.
Comment 8 Andrew Pinski 2006-03-09 00:33:07 UTC
Fixed in 4.0.0.  3.4.6 has been tagged already and has been released (no
announcement has been made but it is up on the ftp server already).