diff --git a/llvm/lib/Target/X86/X86Instr64bit.td b/llvm/lib/Target/X86/X86Instr64bit.td index e7bba79bc1fb..a187f86a107e 100644 --- a/llvm/lib/Target/X86/X86Instr64bit.td +++ b/llvm/lib/Target/X86/X86Instr64bit.td @@ -1251,12 +1251,6 @@ def : Pat<(and GR64:$src, 0xffff), // r & (2^8-1) ==> movz def : Pat<(and GR64:$src, 0xff), (MOVZX64rr8 (i8 (EXTRACT_SUBREG GR64:$src, x86_subreg_8bit)))>; - -// TODO: The following two patterns could be adapted to apply to x86-32, except -// that they'll need some way to deal with the fact that in x86-32 not all GPRs -// have 8-bit subregs. The GR32_ and GR16_ classes are a step in this direction, -// but they aren't ready for this purpose yet. - // r & (2^8-1) ==> movz def : Pat<(and GR32:$src1, 0xff), (MOVZX32rr8 (i8 (EXTRACT_SUBREG GR32:$src1, x86_subreg_8bit)))>, diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index bb90f29b0cbb..c4db58829086 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -2774,6 +2774,16 @@ def : Pat<(i32 (and (loadi32 addr:$src), (i32 65535))),(MOVZX32rm16 addr:$src)>; // r & (2^16-1) ==> movz def : Pat<(and GR32:$src1, 0xffff), (MOVZX32rr16 (i16 (EXTRACT_SUBREG GR32:$src1, x86_subreg_16bit)))>; +// r & (2^8-1) ==> movz +def : Pat<(and GR32:$src1, 0xff), + (MOVZX32rr8 (i8 (EXTRACT_SUBREG (MOV32to32_ GR32:$src1), + x86_subreg_8bit)))>, + Requires<[In32BitMode]>; +// r & (2^8-1) ==> movz +def : Pat<(and GR16:$src1, 0xff), + (MOVZX16rr8 (i8 (EXTRACT_SUBREG (MOV16to16_ GR16:$src1), + x86_subreg_8bit)))>, + Requires<[In32BitMode]>; // (shl x, 1) ==> (add x, x) def : Pat<(shl GR8 :$src1, (i8 1)), (ADD8rr GR8 :$src1, GR8 :$src1)>; diff --git a/llvm/test/CodeGen/X86/zext-inreg-0.ll b/llvm/test/CodeGen/X86/zext-inreg-0.ll index 62c651c83509..1a734642d031 100644 --- a/llvm/test/CodeGen/X86/zext-inreg-0.ll +++ b/llvm/test/CodeGen/X86/zext-inreg-0.ll @@ -8,11 +8,26 @@ ; These should use movzbl instead of 'and 255'. ; This related to not having a ZERO_EXTEND_REG opcode. +define i32 @a(i32 %d) nounwind { + %e = add i32 %d, 1 + %retval = and i32 %e, 255 + ret i32 %retval +} +define i32 @b(float %d) nounwind { + %tmp12 = fptoui float %d to i8 + %retval = zext i8 %tmp12 to i32 + ret i32 %retval +} define i32 @c(i32 %d) nounwind { %e = add i32 %d, 1 %retval = and i32 %e, 65535 ret i32 %retval } +define i64 @d(i64 %d) nounwind { + %e = add i64 %d, 1 + %retval = and i64 %e, 255 + ret i64 %retval +} define i64 @e(i64 %d) nounwind { %e = add i64 %d, 1 %retval = and i64 %e, 65535 diff --git a/llvm/test/CodeGen/X86/zext-inreg-2.ll b/llvm/test/CodeGen/X86/zext-inreg-2.ll deleted file mode 100644 index 1209dac7f6f1..000000000000 --- a/llvm/test/CodeGen/X86/zext-inreg-2.ll +++ /dev/null @@ -1,28 +0,0 @@ -; RUN: llvm-as < %s | llc -march=x86-64 > %t -; RUN: not grep and %t -; RUN: not grep movzbq %t -; RUN: not grep movzwq %t -; RUN: not grep movzlq %t - -; These should use movzbl instead of 'and 255'. -; This related to not having a ZERO_EXTEND_REG opcode. - -; This test was split out of zext-inreg-0.ll because these -; cases don't yet work on x86-32 due to the 8-bit subreg -; issue. - -define i32 @a(i32 %d) nounwind { - %e = add i32 %d, 1 - %retval = and i32 %e, 255 - ret i32 %retval -} -define i32 @b(float %d) nounwind { - %tmp12 = fptoui float %d to i8 - %retval = zext i8 %tmp12 to i32 - ret i32 %retval -} -define i64 @d(i64 %d) nounwind { - %e = add i64 %d, 1 - %retval = and i64 %e, 255 - ret i64 %retval -}