aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSudi Das <sudi.das@arm.com>2020-09-18 15:47:46 +0100
committerOmar Tahir <omar.tahir@arm.com>2020-09-18 17:03:39 +0100
commitc2bb84be4a6e581bbf45891457ee632a07416982 (patch)
treeef187c78b259df5dc5a7fee70d7b35ef0c90b383 /gcc
parent3c7c5f1d4a4b8328fb4c07483cdbfe4ea7762155 (diff)
downloadgcc-c2bb84be4a6e581bbf45891457ee632a07416982.zip
gcc-c2bb84be4a6e581bbf45891457ee632a07416982.tar.gz
gcc-c2bb84be4a6e581bbf45891457ee632a07416982.tar.bz2
[PATCH 2/5][Arm] New pattern for CSINV instructions
This patch adds a new pattern, *thumb2_csinv, for generating CSINV nstructions. This pattern relies on a few general changes that will be used throughout the following patches: - A new macro, TARGET_COND_ARITH, which is only true on 8.1-M Mainline and represents the existence of these conditional instructions. - A change to the cond exec hook, arm_have_conditional_execution, which now returns false if TARGET_COND_ARITH before reload. This allows for some ifcvt transformations when they would usually be disabled. I've written a rather verbose comment (with the risk of over-explaining) as it's a bit of a confusing change. - One new predicate. - *thumb2_movcond has been restricted to only match if !TARGET_COND_ARITH, otherwise it triggers undesirable combines. gcc/ChangeLog: * config/arm/arm.h (TARGET_COND_ARITH): New macro. * config/arm/arm.c (arm_have_conditional_execution): Return false if TARGET_COND_ARITH before reload. * config/arm/predicates.md (arm_comparison_operation): Returns true if comparing CC_REGNUM with constant zero. * config/arm/thumb2.md (*thumb2_csinv): New. (*thumb2_movcond): Don't match if TARGET_COND_ARITH. gcc/testsuite/ChangeLog: * gcc.target/arm/csinv-1.c: New test. Co-authored-by: Omar Tahir <omar.tahir@arm.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/arm/arm.c17
-rw-r--r--gcc/config/arm/arm.h4
-rw-r--r--gcc/config/arm/predicates.md12
-rw-r--r--gcc/config/arm/thumb2.md16
-rw-r--r--gcc/testsuite/gcc.target/arm/csinv-1.c23
5 files changed, 68 insertions, 4 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 932f907..022ef6c 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -29866,12 +29866,23 @@ arm_frame_pointer_required (void)
return false;
}
-/* Only thumb1 can't support conditional execution, so return true if
- the target is not thumb1. */
+/* Implement the TARGET_HAVE_CONDITIONAL_EXECUTION hook.
+ All modes except THUMB1 have conditional execution.
+ If we have conditional arithmetic, return false before reload to
+ enable some ifcvt transformations. */
static bool
arm_have_conditional_execution (void)
{
- return !TARGET_THUMB1;
+ bool has_cond_exec, enable_ifcvt_trans;
+
+ /* Only THUMB1 cannot support conditional execution. */
+ has_cond_exec = !TARGET_THUMB1;
+
+ /* Enable ifcvt transformations if we have conditional arithmetic, but only
+ before reload. */
+ enable_ifcvt_trans = TARGET_COND_ARITH && !reload_completed;
+
+ return has_cond_exec && !enable_ifcvt_trans;
}
/* The AAPCS sets the maximum alignment of a vector to 64 bits. */
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 3887c51..f4d3676 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -177,6 +177,10 @@ emission of floating point pcs attributes. */
#define TARGET_CRC32 (arm_arch_crc)
+/* Thumb-2 but also has some conditional arithmetic instructions like csinc,
+ csinv, etc. */
+#define TARGET_COND_ARITH (arm_arch8_1m_main)
+
/* The following two macros concern the ability to execute coprocessor
instructions for VFPv3 or NEON. TARGET_VFP3/TARGET_VFPD32 are currently
only ever tested when we know we are generating for VFP hardware; we need
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 981eec5..2144520 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -485,6 +485,18 @@
(and (match_operand 0 "expandable_comparison_operator")
(match_test "maybe_get_arm_condition_code (op) != ARM_NV")))
+(define_special_predicate "arm_comparison_operation"
+ (match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
+ ordered,unlt,unle,unge,ungt")
+{
+ if (XEXP (op, 1) != const0_rtx)
+ return false;
+ rtx op0 = XEXP (op, 0);
+ if (!REG_P (op0) || REGNO (op0) != CC_REGNUM)
+ return false;
+ return maybe_get_arm_condition_code (op) != ARM_NV;
+})
+
(define_special_predicate "lt_ge_comparison_operator"
(match_code "lt,ge"))
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 1a5f24e..d648ba1 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -938,6 +938,20 @@
(set_attr "type" "multiple")]
)
+(define_insn "*thumb2_csinv"
+ [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r")
+ (if_then_else:SI
+ (match_operand 1 "arm_comparison_operation" "")
+ (not:SI (match_operand:SI 2 "arm_general_register_operand" "r, r"))
+ (match_operand:SI 3 "reg_or_zero_operand" "r, Pz")))]
+ "TARGET_COND_ARITH"
+ "@
+ csinv\\t%0, %3, %2, %D1
+ csinv\\t%0, zr, %2, %D1"
+ [(set_attr "type" "csel")
+ (set_attr "predicable" "no")]
+)
+
(define_insn "*thumb2_movcond"
[(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
(if_then_else:SI
@@ -947,7 +961,7 @@
(match_operand:SI 1 "arm_rhs_operand" "0,TsI,?TsI")
(match_operand:SI 2 "arm_rhs_operand" "TsI,0,TsI")))
(clobber (reg:CC CC_REGNUM))]
- "TARGET_THUMB2"
+ "TARGET_THUMB2 && !TARGET_COND_ARITH"
"*
if (GET_CODE (operands[5]) == LT
&& (operands[4] == const0_rtx))
diff --git a/gcc/testsuite/gcc.target/arm/csinv-1.c b/gcc/testsuite/gcc.target/arm/csinv-1.c
new file mode 100644
index 0000000..6b5383a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/csinv-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8_1m_main_ok } */
+/* { dg-options "-O2 -march=armv8.1-m.main" } */
+
+int
+test_csinv32_condasn1(int w0, int w1, int w2, int w3)
+{
+ int w4;
+
+ /* { dg-final { scan-assembler "csinv\tr\[0-9\]*.*ne" } } */
+ w4 = (w0 == w1) ? ~w2 : w3;
+ return w4;
+}
+
+int
+test_csinv32_condasn2(int w0, int w1, int w2, int w3)
+{
+ int w4;
+
+ /* { dg-final { scan-assembler "csinv\tr\[0-9\]*.*eq" } } */
+ w4 = (w0 == w1) ? w3 : ~w2;
+ return w4;
+}