aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2017-08-14 18:42:15 +0200
committerUros Bizjak <uros@gcc.gnu.org>2017-08-14 18:42:15 +0200
commit2912db04c1091e5b6a0fd8a464d9ec8a2c5a1fb6 (patch)
treeef84b6e0b05dce8ae6c9c2c51519caf478c49d19 /gcc
parentc7fd21762de653a19dabf837917a8ad6f9491bc0 (diff)
downloadgcc-2912db04c1091e5b6a0fd8a464d9ec8a2c5a1fb6.zip
gcc-2912db04c1091e5b6a0fd8a464d9ec8a2c5a1fb6.tar.gz
gcc-2912db04c1091e5b6a0fd8a464d9ec8a2c5a1fb6.tar.bz2
re PR target/46091 (missed optimization: x86 bt/btc/bts instructions)
PR target/46091 * config/i386/i386.md (*anddi_1_btr): New insn_and_split pattern. (*iordi_1_bts): Ditto. (*xordi_1_btc): Ditto. testsuite/ChangeLog: PR target/46091 * gcc.target/i386/pr46091-1.c: New test. * gcc.target/i386/pr46091-2.c: Ditto. * gcc.target/i386/pr46091-3.c: Ditto. From-SVN: r251095
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/i386/i386.md65
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.target/i386/pr46091-1.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr46091-2.c9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr46091-3.c9
6 files changed, 106 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8bc4e22..4c147b0 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2017-08-14 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/46091
+ * config/i386/i386.md (*anddi_1_btr): New insn_and_split pattern.
+ (*iordi_1_bts): Ditto.
+ (*xordi_1_btc): Ditto.
+
2017-08-14 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
PR target/79845
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 8cf6d21..059a518 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -8267,6 +8267,27 @@
(const_string "*")))
(set_attr "mode" "SI,DI,DI,SI")])
+(define_insn_and_split "*anddi_1_btr"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (and:DI
+ (match_operand:DI 1 "register_operand" "%0")
+ (match_operand:DI 2 "const_int_operand" "n")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT && TARGET_USE_BT
+ && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
+ "#"
+ "&& reload_completed"
+ [(parallel [(set (zero_extract:DI (match_dup 0)
+ (const_int 1)
+ (match_dup 3))
+ (const_int 0))
+ (clobber (reg:CC FLAGS_REG))])]
+ "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "znver1_decode" "double")
+ (set_attr "mode" "DI")])
+
;; Turn *anddi_1 into *andsi_1_zext if possible.
(define_split
[(set (match_operand:DI 0 "register_operand")
@@ -8791,6 +8812,50 @@
[(set_attr "type" "alu")
(set_attr "mode" "<MODE>")])
+(define_insn_and_split "*iordi_1_bts"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (ior:DI
+ (match_operand:DI 1 "register_operand" "%0")
+ (match_operand:DI 2 "const_int_operand" "n")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT && TARGET_USE_BT
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
+ "#"
+ "&& reload_completed"
+ [(parallel [(set (zero_extract:DI (match_dup 0)
+ (const_int 1)
+ (match_dup 3))
+ (const_int 1))
+ (clobber (reg:CC FLAGS_REG))])]
+ "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "znver1_decode" "double")
+ (set_attr "mode" "DI")])
+
+(define_insn_and_split "*xordi_1_btc"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (xor:DI
+ (match_operand:DI 1 "register_operand" "%0")
+ (match_operand:DI 2 "const_int_operand" "n")))
+ (clobber (reg:CC FLAGS_REG))]
+ "TARGET_64BIT && TARGET_USE_BT
+ && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
+ "#"
+ "&& reload_completed"
+ [(parallel [(set (zero_extract:DI (match_dup 0)
+ (const_int 1)
+ (match_dup 3))
+ (not:DI (zero_extract:DI (match_dup 0)
+ (const_int 1)
+ (match_dup 3))))
+ (clobber (reg:CC FLAGS_REG))])]
+ "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
+ [(set_attr "type" "alu1")
+ (set_attr "prefix_0f" "1")
+ (set_attr "znver1_decode" "double")
+ (set_attr "mode" "DI")])
+
;; See comment for addsi_1_zext why we do use nonimmediate_operand
(define_insn "*<code>si_1_zext"
[(set (match_operand:DI 0 "register_operand" "=r")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index bfe2f78..18dac95 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2017-08-14 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/46091
+ * gcc.target/i386/pr46091-1.c: New test.
+ * gcc.target/i386/pr46091-2.c: Ditto.
+ * gcc.target/i386/pr46091-3.c: Ditto.
+
2017-08-14 Wilco Dijkstra <wdijkstr@arm.com>
PR target/81643
diff --git a/gcc/testsuite/gcc.target/i386/pr46091-1.c b/gcc/testsuite/gcc.target/i386/pr46091-1.c
new file mode 100644
index 0000000..adca01f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr46091-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+unsigned long long test (unsigned long long a)
+{
+ return a & ~(1ull << 55);
+}
+
+/* { dg-final { scan-assembler "btr" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr46091-2.c b/gcc/testsuite/gcc.target/i386/pr46091-2.c
new file mode 100644
index 0000000..1743753
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr46091-2.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+unsigned long long test (unsigned long long a)
+{
+ return a | (1ull << 55);
+}
+
+/* { dg-final { scan-assembler "bts" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr46091-3.c b/gcc/testsuite/gcc.target/i386/pr46091-3.c
new file mode 100644
index 0000000..c8091e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr46091-3.c
@@ -0,0 +1,9 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2" } */
+
+unsigned long long test (unsigned long long a)
+{
+ return a ^ (1ull << 55);
+}
+
+/* { dg-final { scan-assembler "btc" } } */