aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/config/i386/i386.md9
-rw-r--r--gcc/testsuite/gcc.target/i386/pr103611-1.c30
2 files changed, 39 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 9d7d116..f6d9c4b 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -10542,6 +10542,15 @@
(match_dup 2)) 0))
(clobber (reg:CC FLAGS_REG))])]
{
+ /* Handle the case where INTVAL (operands[2]) == 0. */
+ if (operands[2] == const0_rtx)
+ {
+ if (!rtx_equal_p (operands[0], operands[1]))
+ emit_move_insn (operands[0], operands[1]);
+ else
+ emit_note (NOTE_INSN_DELETED);
+ DONE;
+ }
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
diff --git a/gcc/testsuite/gcc.target/i386/pr103611-1.c b/gcc/testsuite/gcc.target/i386/pr103611-1.c
new file mode 100644
index 0000000..7d8ac9d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr103611-1.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O2 -msse4" } */
+typedef int __v4si __attribute__ ((__vector_size__ (16)));
+
+long long ior_1(__v4si v) {
+ unsigned int loVal = (unsigned int)v[0];
+ unsigned int hiVal = (unsigned int)v[1];
+ return (long long)(loVal) | ((long long)(hiVal) << 32);
+}
+
+long long ior_2(__v4si v) {
+ unsigned int loVal = (unsigned int)v[2];
+ unsigned int hiVal = (unsigned int)v[3];
+ return (long long)(loVal) | ((long long)(hiVal) << 32);
+}
+
+long long xor_1(__v4si v) {
+ unsigned int loVal = (unsigned int)v[0];
+ unsigned int hiVal = (unsigned int)v[1];
+ return (long long)(loVal) ^ ((long long)(hiVal) << 32);
+}
+
+long long xor_2(__v4si v) {
+ unsigned int loVal = (unsigned int)v[2];
+ unsigned int hiVal = (unsigned int)v[3];
+ return (long long)(loVal) ^ ((long long)(hiVal) << 32);
+}
+/* { dg-final { scan-assembler-not "\torb\t\\\$0," } } */
+/* { dg-final { scan-assembler-not "\txorb\t\\\$0," } } */
+