Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions gcc/config/arc/arc.md
Original file line number Diff line number Diff line change
Expand Up @@ -6268,7 +6268,7 @@ archs4x, archs4xd"
;; Split sign-extension of single least significant bit as and x,$1;neg x
(define_insn_and_split "*extvsi_1_0"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI (match_operand:SI 1 "register_operand" "0")
(sign_extract:SI (match_operand:SI 1 "register_operand" "r")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was under the impression that this was a functional issue.
But the resulting RTL pattern is correct?

This is just for performance?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first define_insn_and_split has potential to generate incorrect code.

For the second one there was a change from && 1 to &&reload_completed and at the same time there was a change from (sign_extract:SI (match_operand:SI 1 "register_operand" "0")
to (sign_extract:SI (match_operand:SI 1 "register_operand" "r").

My point is that there is no need to have the both as the second change (i.e, (sign_extract:SI (match_operand:SI 1 "register_operand" "0") to (sign_extract:SI (match_operand:SI 1 "register_operand" "r")) is enough allowing the split to take place even before ra.

(const_int 1)
(const_int 0)))]
"!TARGET_BARREL_SHIFTER"
Expand All @@ -6288,7 +6288,7 @@ archs4x, archs4xd"
&& IN_RANGE (INTVAL (operands[2]), 2,
(optimize_insn_for_size_p () ? 28 : 30))"
"#"
"&& reload_completed"
"&& 1"
[(set (match_dup 0) (and:SI (match_dup 1) (match_dup 3)))
(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 4)))
(set (match_dup 0) (minus:SI (match_dup 0) (match_dup 4)))]
Expand Down
67 changes: 67 additions & 0 deletions gcc/testsuite/gcc.target/arc/extvsi-sign-extract.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* { dg-do run } */
/* { dg-options "-O2 -mcpu=em -save-temps" } */

#include <stdio.h>
#include <stdlib.h>

/* Test multi-bit Extraction Pattern (*extvsi_n_0). */
struct bitstruct {
unsigned a : 21;
unsigned b : 8;
unsigned c : 2;
int d : 17;
} __attribute__((packed));

static volatile struct bitstruct bits = {
.a = 0x100,
.b = 0x2f,
.c = 0,
.d = 0
};

volatile int global_d;

/* Test snigle-bit Extraction Pattern (*extvsi_1_0). */
struct source_struct {
int target_bit : 1;
unsigned int padding : 31;
} __attribute__((packed));

static volatile struct source_struct data = {
.target_bit = 1,
.padding = 0xabcdef
};

volatile int destination;

int
main (void)
{
/* 1. Execute Multi-bit Sign-Extract Test */
global_d = bits.d;
if (global_d != 0)
{
printf ("FAIL: Multi-bit extract (*extvsi_n_0) failed. Expected 0, got %d\n", global_d);
abort ();
}

/* 2. Execute Single-bit Sign-Extract Test */
destination = data.target_bit;
if (destination != -1)
{
printf ("FAIL: Single-bit extract (*extvsi_1_0) failed. Expected -1, got %d\n", destination);
abort ();
}

printf ("PASS: Both sign-extract patterns executed successfully.\n");
return 0;
}

/* Check that the extvsi_n_0 split got triggered. */
/* { dg-final { scan-assembler "bmsk.*,16" } } */
/* { dg-final { scan-assembler "bxor.*,16" } } */
/* { dg-final { scan-assembler "sub.*,65536" } } */

/* Check that the extvsi_1_0 split got triggered. */
/* { dg-final { scan-assembler "bmsk.*,0" } } */
/* { dg-final { scan-assembler "neg" } } */