public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Vineet Gupta <vineetg@rivosinc.com>
To: gcc@gcc.gnu.org
Cc: Christoph Muellner <cmuellner@gcc.gnu.org>,
	Philipp Tomsich <philipp.tomsich@vrull.eu>,
	Kito Cheng <kito.cheng@sifive.com>,
	Jeff Law <jeffreyalaw@gmail.com>,
	Jim Wilson <jim.wilson.gcc@gmail.com>
Subject: Redundant constants in coremark crc8 for RISCV/aarch64 (no-if-conversion)
Date: Fri, 14 Oct 2022 08:56:59 -0700	[thread overview]
Message-ID: <a4544513-32bd-4bfc-b3f1-6dde3e82bbf7@rivosinc.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 2760 bytes --]

Hi,

When analyzing coremark build for RISC-V, noticed redundant constants 
not being eliminated. While this is a recurrent issue with RV, this 
specific instance is not unique to RV as I can trigger similar output on 
aarch64 with -fno-if-conversion, hence something which could be 
addressed in common passes.

-O3 -march=rv64gc_zba_zbb_zbc_zbs

crcu8:
	xor	a3,a0,a1
	andi	a3,a3,1
	srli	a4,a0,1
	srli	a5,a1,1
	beq	a3,zero,.L2

	li	a3,-24576	# 0xFFFF_A000
	addi	a3,a3,1		# 0xFFFF_A001
	xor	a5,a5,a3
	zext.h	a5,a5

.L2:
	xor	a4,a4,a5	
	andi	a4,a4,1	
	srli	a3,a0,2	
	srli	a5,a5,1	
	beq	a4,zero,.L3	

	li	a4,-24576	# 0xFFFF_A000
	addi	a4,a4,1		# 0xFFFF_A001
	xor	a5,a5,a4	
	zext.h	a5,a5		

.L3:
	xor	a3,a3,a5	
	andi	a3,a3,1	
	srli	a4,a0,3	
	srli	a5,a5,1	
	beq	a3,zero,.L4

	li	a3,-24576	# 0xFFFF_A000
	addi	a3,a3,1		# 0xFFFF_A001
...
...

I see that with small tests cse1 is able to substitute redundant 
constant reg with equivalent old reg.

cse_insn
    make_regs_equiv()
    ..
    canon_reg()

e.g.
void foo(void)
{
    bar(2072, 2096);
}

foo:
     li	a0,4096
     addi	a1,a0,-2000
     addi	a0,a0,-2024
     tail	bar

And it seems to even work across basic blocks.

e.g.

void foo(int x)	# -O2
{
     bar1(2072);
     foo2();
     if (x)
	bar2(2096);
}

foo:
  ...
     li s1, 4096
     addi a0, s1, -2024
  ...
     addi a0, a1, -2000
     tail bar2

It seems cse redundancy elimination logic is scoped to "paths" created 
by cse_find_path() and those seems to chain only 2 basic blocks.

;; Following path with 17 sets: 2 3
;; Following path with 15 sets: 4 5
;; Following path with 15 sets: 6 7
;; Following path with 15 sets: 8 9
;; Following path with 15 sets: 10 11
;; Following path with 15 sets: 12 13
;; Following path with 15 sets: 14 15
;; Following path with 13 sets: 16 17
;; Following path with 2 sets: 18
...

While in this case the BBs containing the dups are 6, 8, ...

(note 36 35 37 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
(insn 37 36 38 6 (set (reg:DI 196)
         (const_int -24576 [0xffffffffffffa000])) 
"../../coremark-crc8.c":23:17 -1
      (nil))
...
(note 54 53 55 8 [bb 8] NOTE_INSN_BASIC_BLOCK)
(insn 55 54 56 8 (set (reg:DI 207)
         (const_int -24576 [0xffffffffffffa000])) 
"../../coremark-crc8.c":23:17 -1
      (nil))

The path construction logic in cse seems non trivial for someone just 
starting to dig into that code so I'd appreciate some insight.

Also I'm wondering if cse is the right place to do this at all, or 
should it be done in gcse/PRE ?

TIA
-Vineet

P.S. With the proposed RV cond ops extension if-conversion could elide 
this specific instance of problem, however redundant constants are a 
common enough nuisance in RV codegen whcih we need to tackle, specially 
when it is typically a 2 instruction seq.

[-- Attachment #2: coremark-crc8.c --]
[-- Type: text/x-csrc, Size: 536 bytes --]

typedef unsigned short ee_u16;
typedef unsigned char ee_u8;

ee_u16
crcu8(ee_u8 data, ee_u16 crc)
{
    ee_u8 i = 0, x16 = 0, carry = 0;

    for (i = 0; i < 8; i++)
    {
        x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1));
        data >>= 1;

        if (x16 == 1)
        {
            crc ^= 0x4002;
            carry = 1;
        }
        else
            carry = 0;
        crc >>= 1;
        if (carry)
            crc |= 0x8000;	// set MSB bit
        else
            crc &= 0x7fff;	// clear MSB bit
    }
    return crc;
}

             reply	other threads:[~2022-10-14 15:57 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-14 15:56 Vineet Gupta [this message]
2022-10-14 16:54 ` Jeff Law
2022-10-18 21:51   ` Vineet Gupta
2022-10-18 23:36     ` Jeff Law
2022-10-19  2:09       ` Vineet Gupta
2022-10-19  3:42         ` Jeff Law
2022-10-19  7:46           ` Richard Biener
2022-10-19 13:30             ` Jeff Law

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=a4544513-32bd-4bfc-b3f1-6dde3e82bbf7@rivosinc.com \
    --to=vineetg@rivosinc.com \
    --cc=cmuellner@gcc.gnu.org \
    --cc=gcc@gcc.gnu.org \
    --cc=jeffreyalaw@gmail.com \
    --cc=jim.wilson.gcc@gmail.com \
    --cc=kito.cheng@sifive.com \
    --cc=philipp.tomsich@vrull.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).