nvptx: Add support for PTX's cnot instruction.

This is a simple patch, now that the nvptx backend has transitioned
to STORE_FLAG_VALUE=1, that adds support for NVidia's cnot instruction,
that implements C/C++ style logical negation.

Previously, the simple function:

int foo(int x) { return !x; }

on nvptx-none with -O2 would generate:

	mov.u32 %r24, %ar0;
	setp.eq.u32     %r28, %r24, 0;
	selp.u32        %value, 1, 0, %r28;

with this patch, GCC now generates:

	mov.u32 %r24, %ar0;
	cnot.b32        %value, %r24;

2022-01-07  Roger Sayle  <roger@nextmovesoftware.com>

gcc/ChangeLog
	* config/nvptx/nvptx.md (*cnot<mode>2): New define_insn.

gcc/testsuite/ChangeLog
	* gcc.target/nvptx/cnot-1.c: New test case.
This commit is contained in:
Roger Sayle 2022-01-07 09:57:21 +00:00
parent add37d3bf4
commit 659f8161f6
2 changed files with 101 additions and 0 deletions

View File

@ -592,6 +592,13 @@
""
"%.\\tnot.b%T0\\t%0, %1;")
(define_insn "*cnot<mode>2"
[(set (match_operand:HSDIM 0 "nvptx_register_operand" "=R")
(eq:HSDIM (match_operand:HSDIM 1 "nvptx_register_operand" "R")
(const_int 0)))]
""
"%.\\tcnot.b%T0\\t%0, %1;")
(define_insn "bitrev<mode>2"
[(set (match_operand:SDIM 0 "nvptx_register_operand" "=R")
(unspec:SDIM [(match_operand:SDIM 1 "nvptx_register_operand" "R")]

View File

@ -0,0 +1,94 @@
/* { dg-do compile } */
/* { dg-options "-O2" } */
int test1(int x)
{
return !x;
}
int test2(int x)
{
return x ? 0 : 1;
}
int test3(int x)
{
return (x == 0) ? 1 : 0;
}
unsigned int test4(unsigned int x)
{
return !x;
}
unsigned int test5(unsigned int x)
{
return x ? 0 : 1;
}
unsigned int test6(unsigned int x)
{
return (x == 0) ? 1 : 0;
}
short test7(short x)
{
return !x;
}
short test8(short x)
{
return x ? 0 : 1;
}
short test9(short x)
{
return (x == 0) ? 1 : 0;
}
unsigned short test10(unsigned short x)
{
return !x;
}
unsigned short test11(unsigned short x)
{
return x ? 0 : 1;
}
unsigned short test12(unsigned short x)
{
return (x == 0) ? 1 : 0;
}
long test13(long x)
{
return !x;
}
long test14(long x)
{
return x ? 0 : 1;
}
long test15(long x)
{
return (x == 0) ? 1: 0;
}
unsigned long test16(unsigned long x)
{
return !x;
}
unsigned long test17(unsigned long x)
{
return x ? 0 : 1;
}
unsigned long test18(unsigned long x)
{
return (x == 0) ? 1 : 0;
}
/* { dg-final { scan-assembler-times "cnot.b" 18 } } */