diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index eb42a4b2119d5e..f24334312c116a 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -5595,9 +5595,13 @@ static unsigned convertALUrr2ALUri(unsigned Opc) { case X86::FROM: \ return X86::TO; FROM_TO(TEST64rr, TEST64ri32) + FROM_TO(CTEST64rr, CTEST64ri32) FROM_TO(CMP64rr, CMP64ri32) + FROM_TO(CCMP64rr, CCMP64ri32) FROM_TO(TEST32rr, TEST32ri) + FROM_TO(CTEST32rr, CTEST32ri) FROM_TO(CMP32rr, CMP32ri) + FROM_TO(CCMP32rr, CCMP32ri) #undef FROM_TO } } @@ -5697,7 +5701,8 @@ bool X86InstrInfo::foldImmediateImpl(MachineInstr &UseMI, MachineInstr *DefMI, UseMI.findRegisterUseOperandIdx(Reg) != 2) return false; // For CMP instructions the immediate can only be at index 1. - if ((NewOpc == X86::CMP64ri32 || NewOpc == X86::CMP32ri) && + if (((NewOpc == X86::CMP64ri32 || NewOpc == X86::CMP32ri) || + (NewOpc == X86::CCMP64ri32 || NewOpc == X86::CCMP32ri)) && UseMI.findRegisterUseOperandIdx(Reg) != 1) return false; @@ -5742,7 +5747,7 @@ bool X86InstrInfo::foldImmediateImpl(MachineInstr &UseMI, MachineInstr *DefMI, unsigned Op1 = 1, Op2 = CommuteAnyOperandIndex; unsigned ImmOpNum = 2; if (!UseMI.getOperand(0).isDef()) { - Op1 = 0; // TEST, CMP + Op1 = 0; // TEST, CMP, CTEST, CCMP ImmOpNum = 1; } if (Opc == TargetOpcode::COPY) diff --git a/llvm/test/CodeGen/X86/apx/foldimmediate.mir b/llvm/test/CodeGen/X86/apx/foldimmediate.mir new file mode 100644 index 00000000000000..310fc64841f7a5 --- /dev/null +++ b/llvm/test/CodeGen/X86/apx/foldimmediate.mir @@ -0,0 +1,70 @@ +# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 3 +# RUN: llc -mtriple=x86_64-- -run-pass=peephole-opt %s -o - | FileCheck %s +--- | + define void @foldImmediate() { ret void } +... +--- +# Check that immediates can be folded into ALU instructions. +name: foldImmediate +registers: + - { id: 0, class: gr32 } + - { id: 1, class: gr32 } + - { id: 2, class: gr32 } + - { id: 3, class: gr32 } + - { id: 4, class: gr32 } + - { id: 5, class: gr32 } + - { id: 6, class: gr32 } + - { id: 7, class: gr64 } + - { id: 8, class: gr64 } + - { id: 9, class: gr64 } + - { id: 10, class: gr64 } + - { id: 11, class: gr64 } + - { id: 12, class: gr64 } + - { id: 13, class: gr64 } + - { id: 14, class: gr64 } + - { id: 15, class: gr64 } + - { id: 16, class: gr32 } + - { id: 17, class: gr64 } + - { id: 18, class: gr32 } + +body: | + bb.0: + liveins: $rdi, $rsi + + ; CHECK-LABEL: name: foldImmediate + ; CHECK: liveins: $rdi, $rsi + ; CHECK-NEXT: {{ $}} + ; CHECK-NEXT: [[MOV32ri:%[0-9]+]]:gr32 = MOV32ri 81 + ; CHECK-NEXT: [[COPY:%[0-9]+]]:gr32 = COPY $edi + ; CHECK-NEXT: CTEST32ri [[COPY]], 81, 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + ; CHECK-NEXT: CCMP32ri [[COPY]], 81, 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + ; CHECK-NEXT: [[SUBREG_TO_REG:%[0-9]+]]:gr64 = SUBREG_TO_REG 0, killed [[MOV32ri]], %subreg.sub_32bit + ; CHECK-NEXT: [[COPY1:%[0-9]+]]:gr64 = COPY $rsi + ; CHECK-NEXT: CTEST64ri32 [[COPY1]], 81, 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + ; CHECK-NEXT: CCMP64ri32 [[COPY1]], 81, 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + ; CHECK-NEXT: CCMP64rr [[SUBREG_TO_REG]], [[COPY1]], 2, 10, implicit-def $eflags, implicit $eflags + ; CHECK-NEXT: NOOP implicit $eflags + %0 = MOV32ri 81 + %1 = COPY $edi + + CTEST32rr %0, %1, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags + + CCMP32rr %1, %0, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags + + %7 = SUBREG_TO_REG 0, killed %0:gr32, %subreg.sub_32bit + %8 = COPY $rsi + + CTEST64rr %8, %7, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags + + CCMP64rr %8, %7, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags + CCMP64rr %7, %8, 2, 10, implicit-def $eflags, implicit $eflags + NOOP implicit $eflags +...