This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AArch64/GCC] PR64304, miscompilation with -mgeneral-regs-only


as discussed here https://gcc.gnu.org/ml/gcc-patches/2015-01/msg00563.html

the problem is aarch64 hardware only support left shift truncation for SI/DI,
while SHIFT_COUNT_TRUNCATED is enabled for all mode including QI/HI, which is
inconsistent with hardware feature.

there are two patterns defined for ashift:QI/HI, one for shift amount in register,
one for shift amount as constant.

this patch only remove the pattern for shift amount in register which cause the trouble.

no regression on bare metal test.
bootstrap OK.

ok for trunk?


2015-01-15 Jiong. Wang (jiong.wang@arm.com)
gcc/
PR64304
  * config/aarch64/aarch64.md (define_insn "*ashl<mode>3_insn"): Deleted.
  (ashl<mode>3): Don't expand if operands[2] is not constant.

gcc/testsuite/
  * gcc.target/aarch64/pr64304.c: New testcase.
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 597ff8c..49d6690 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -3091,6 +3091,8 @@
 	    DONE;
           }
       }
+    else
+      DONE;
   }
 )
 
@@ -3315,15 +3317,6 @@
   [(set_attr "type" "shift_reg")]
 )
 
-(define_insn "*ashl<mode>3_insn"
-  [(set (match_operand:SHORT 0 "register_operand" "=r")
-	(ashift:SHORT (match_operand:SHORT 1 "register_operand" "r")
-		      (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss")))]
-  ""
-  "lsl\\t%<w>0, %<w>1, %<w>2"
-  [(set_attr "type" "shift_reg")]
-)
-
 (define_insn "*<optab><mode>3_insn"
   [(set (match_operand:SHORT 0 "register_operand" "=r")
 	(ASHIFT:SHORT (match_operand:SHORT 1 "register_operand" "r")
diff --git a/gcc/testsuite/gcc.target/aarch64/pr64304.c b/gcc/testsuite/gcc.target/aarch64/pr64304.c
new file mode 100644
index 0000000..5423bb3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr64304.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 --save-temps" } */
+
+unsigned char byte = 0;
+
+void
+set_bit (unsigned int bit, unsigned char value)
+{
+  unsigned char mask = (unsigned char) (1 << (bit & 7));
+
+  if (! value)
+    byte &= (unsigned char)~mask;
+  else
+    byte |= mask;
+  /* { dg-final { scan-assembler "and\tw\[0-9\]+, w\[0-9\]+, 7" } } */
+}
+
+/* { dg-final { cleanup-saved-temps } } */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]