diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 298e4b303486fcc864c5676be574af30024b92f1..fd30c573c270f147c944061d56bfa390f4bf0a95 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1510,7 +1510,7 @@
 (define_insn_and_split "*cmp<dwi>_doubleword"
   [(set (reg:CCZ FLAGS_REG)
 	(compare:CCZ (match_operand:<DWI> 0 "nonimmediate_operand")
-		     (match_operand:<DWI> 1 "x86_64_hilo_general_operand")))]
+		     (match_operand:<DWI> 1 "general_operand")))]
   "ix86_pre_reload_split ()"
   "#"
   "&& 1"
@@ -1544,7 +1544,12 @@
   else if (operands[0] == constm1_rtx)
     emit_insn (gen_one_cmpl<mode>2 (operands[4], operands[1]));
   else
-    emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
+    {
+      if (CONST_SCALAR_INT_P (operands[1])
+	  && !x86_64_immediate_operand (operands[1], <MODE>mode))
+	operands[1] = force_reg (<MODE>mode, operands[1]);
+      emit_insn (gen_xor<mode>3 (operands[4], operands[0], operands[1]));
+    }
 
   if (operands[3] == const0_rtx)
     operands[5] = operands[2];
@@ -1558,7 +1563,12 @@
       else if (operands[2] == constm1_rtx)
 	emit_insn (gen_one_cmpl<mode>2 (operands[5], operands[3]));
       else
-	emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
+	{
+	  if (CONST_SCALAR_INT_P (operands[3])
+	      && !x86_64_immediate_operand (operands[3], <MODE>mode))
+	    operands[3] = force_reg (<MODE>mode, operands[3]);
+	  emit_insn (gen_xor<mode>3 (operands[5], operands[2], operands[3]));
+	}
     }
 })
 
diff --git a/gcc/testsuite/gcc.target/i386/cmpti1.c b/gcc/testsuite/gcc.target/i386/cmpti1.c
new file mode 100644
index 0000000000000000000000000000000000000000..1c5f121e54437ec3eeb03468627a5dc6739852bb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cmpti1.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+int eq(__int128 x, __int128 y) { return x == y; }
+int ne(__int128 x, __int128 y) { return x != y; }
+/* { dg-final { scan-assembler-times "xorq" 4 } } */
+/* { dg-final { scan-assembler-times "setne" 1 } } */
+/* { dg-final { scan-assembler-times "sete" 1 } } */
+
diff --git a/gcc/testsuite/gcc.target/i386/cmpti2.c b/gcc/testsuite/gcc.target/i386/cmpti2.c
new file mode 100644
index 0000000000000000000000000000000000000000..ad9572901ce5ab997794b4ba38704808728b15a2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cmpti2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+__int128 x;
+__int128 y;
+
+int eq() { return x == y; }
+int ne() { return x != y; }
+
+/* { dg-final { scan-assembler-times "xorq" 4 } } */
+/* { dg-final { scan-assembler-times "setne" 1 } } */
+/* { dg-final { scan-assembler-times "sete" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/cmpti3.c b/gcc/testsuite/gcc.target/i386/cmpti3.c
new file mode 100644
index 0000000000000000000000000000000000000000..302efd2ad59eb582c436784d97874f7150da2d51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/cmpti3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+__int128 x;
+int foo()
+{
+    __int128 t = 0x1234567890abcdefLL;
+    return x == t;
+}
+
+/* { dg-final { scan-assembler-times "movabsq" 1 } } */
+/* { dg-final { scan-assembler-times "xorq" 1 } } */
+/* { dg-final { scan-assembler-not "xorl" } } */