[llvm] [X86][GlobalISel] Add instruction selection for G_SELECT (PR #70753)

Evgenii Kudriashov via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 13 15:52:29 PST 2023


https://github.com/e-kud updated https://github.com/llvm/llvm-project/pull/70753

>From e7a99b063d2a6f50ac8feaae6be27dd5189c00ca Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Wed, 18 Oct 2023 09:28:51 -0700
Subject: [PATCH 1/4] [X86][GlobalISel] Add instruction selection for G_SELECT

---
 .../X86/GISel/X86InstructionSelector.cpp      |  45 ++
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp |   9 +-
 .../test/CodeGen/X86/fast-isel-select-cmov.ll |  76 ---
 llvm/test/CodeGen/X86/isel-select-cmov.ll     | 455 ++++++++++++++++++
 4 files changed, 504 insertions(+), 81 deletions(-)
 delete mode 100644 llvm/test/CodeGen/X86/fast-isel-select-cmov.ll
 create mode 100644 llvm/test/CodeGen/X86/isel-select-cmov.ll

diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index 6157dafb5c5106c..b68d22f6c1c3914 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -116,6 +116,8 @@ class X86InstructionSelector : public InstructionSelector {
   bool selectImplicitDefOrPHI(MachineInstr &I, MachineRegisterInfo &MRI) const;
   bool selectMulDivRem(MachineInstr &I, MachineRegisterInfo &MRI,
                        MachineFunction &MF) const;
+  bool selectSelect(MachineInstr &I, MachineRegisterInfo &MRI,
+                    MachineFunction &MF) const;
   bool selectIntrinsicWSideEffects(MachineInstr &I, MachineRegisterInfo &MRI,
                                    MachineFunction &MF) const;
 
@@ -429,6 +431,8 @@ bool X86InstructionSelector::select(MachineInstr &I) {
   case TargetOpcode::G_SREM:
   case TargetOpcode::G_UREM:
     return selectMulDivRem(I, MRI, MF);
+  case TargetOpcode::G_SELECT:
+    return selectSelect(I, MRI, MF);
   case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
     return selectIntrinsicWSideEffects(I, MRI, MF);
   }
@@ -1789,6 +1793,47 @@ bool X86InstructionSelector::selectMulDivRem(MachineInstr &I,
   return true;
 }
 
+bool X86InstructionSelector::selectSelect(MachineInstr &I,
+                                          MachineRegisterInfo &MRI,
+                                          MachineFunction &MF) const {
+  unsigned DstReg = I.getOperand(0).getReg();
+  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST32rr))
+      .addReg(I.getOperand(1).getReg())
+      .addReg(I.getOperand(1).getReg());
+
+  unsigned OpCmp;
+  LLT Ty = MRI.getType(DstReg);
+  switch (Ty.getSizeInBits()) {
+  default:
+    return false;
+  case 8:
+    OpCmp = X86::CMOV_GR8;
+    break;
+  case 16:
+    OpCmp = STI.canUseCMOV() ? X86::CMOV16rr : X86::CMOV_GR16;
+    break;
+  case 32:
+    OpCmp = STI.canUseCMOV() ? X86::CMOV32rr : X86::CMOV_GR32;
+    break;
+  case 64:
+    assert(STI.is64Bit() && STI.canUseCMOV());
+    OpCmp = X86::CMOV64rr;
+    break;
+  }
+  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp), DstReg)
+      .addReg(I.getOperand(2).getReg())
+      .addReg(I.getOperand(3).getReg())
+      .addImm(5);
+  const TargetRegisterClass *DstRC = getRegClass(Ty, DstReg, MRI);
+  if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
+    LLVM_DEBUG(dbgs() << "Failed to constrain CMOV\n");
+    return false;
+  }
+
+  I.eraseFromParent();
+  return true;
+}
+
 bool X86InstructionSelector::selectIntrinsicWSideEffects(
     MachineInstr &I, MachineRegisterInfo &MRI, MachineFunction &MF) const {
 
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 03af2b9e537c0c5..0e4a656838a4a94 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -521,11 +521,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
 
   // todo: vectors and address spaces
   getActionDefinitionsBuilder(G_SELECT)
-       .legalFor({{s8, s32}, {s16, s32}, {s32, s32}, {s64, s32},
-                  {p0, s32}})
-    .widenScalarToNextPow2(0, /*Min=*/8)
-    .clampScalar(0, s8, sMaxScalar)
-    .clampScalar(1, s32, s32);
+      .legalFor({{s8, s32}, {s16, s32}, {s32, s32}, {s64, s32}, {p0, s32}})
+      .widenScalarToNextPow2(0, /*Min=*/8)
+      .clampScalar(0, s8, sMaxScalar)
+      .clampScalar(1, s32, s32);
 
   // memory intrinsics
   getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
diff --git a/llvm/test/CodeGen/X86/fast-isel-select-cmov.ll b/llvm/test/CodeGen/X86/fast-isel-select-cmov.ll
deleted file mode 100644
index a5efb6f06b86d28..000000000000000
--- a/llvm/test/CodeGen/X86/fast-isel-select-cmov.ll
+++ /dev/null
@@ -1,76 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10                  | FileCheck %s
-; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 -mattr=+avx512f  | FileCheck %s
-
-; Test conditional move for the supported types (i16, i32, and i32) and
-; conditon input (argument or cmp). Currently i8 is not supported.
-
-define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroext %b) {
-; CHECK-LABEL: select_cmov_i16:
-; CHECK:       ## %bb.0:
-; CHECK-NEXT:    testb $1, %dil
-; CHECK-NEXT:    cmovew %dx, %si
-; CHECK-NEXT:    movzwl %si, %eax
-; CHECK-NEXT:    retq
-  %1 = select i1 %cond, i16 %a, i16 %b
-  ret i16 %1
-}
-
-define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
-; CHECK-LABEL: select_cmp_cmov_i16:
-; CHECK:       ## %bb.0:
-; CHECK-NEXT:    cmpw %si, %di
-; CHECK-NEXT:    cmovbw %di, %si
-; CHECK-NEXT:    movzwl %si, %eax
-; CHECK-NEXT:    retq
-  %1 = icmp ult i16 %a, %b
-  %2 = select i1 %1, i16 %a, i16 %b
-  ret i16 %2
-}
-
-define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
-; CHECK-LABEL: select_cmov_i32:
-; CHECK:       ## %bb.0:
-; CHECK-NEXT:    movl %esi, %eax
-; CHECK-NEXT:    testb $1, %dil
-; CHECK-NEXT:    cmovel %edx, %eax
-; CHECK-NEXT:    retq
-  %1 = select i1 %cond, i32 %a, i32 %b
-  ret i32 %1
-}
-
-define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
-; CHECK-LABEL: select_cmp_cmov_i32:
-; CHECK:       ## %bb.0:
-; CHECK-NEXT:    movl %esi, %eax
-; CHECK-NEXT:    cmpl %esi, %edi
-; CHECK-NEXT:    cmovbl %edi, %eax
-; CHECK-NEXT:    retq
-  %1 = icmp ult i32 %a, %b
-  %2 = select i1 %1, i32 %a, i32 %b
-  ret i32 %2
-}
-
-define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
-; CHECK-LABEL: select_cmov_i64:
-; CHECK:       ## %bb.0:
-; CHECK-NEXT:    movq %rsi, %rax
-; CHECK-NEXT:    testb $1, %dil
-; CHECK-NEXT:    cmoveq %rdx, %rax
-; CHECK-NEXT:    retq
-  %1 = select i1 %cond, i64 %a, i64 %b
-  ret i64 %1
-}
-
-define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) {
-; CHECK-LABEL: select_cmp_cmov_i64:
-; CHECK:       ## %bb.0:
-; CHECK-NEXT:    movq %rsi, %rax
-; CHECK-NEXT:    cmpq %rsi, %rdi
-; CHECK-NEXT:    cmovbq %rdi, %rax
-; CHECK-NEXT:    retq
-  %1 = icmp ult i64 %a, %b
-  %2 = select i1 %1, i64 %a, i64 %b
-  ret i64 %2
-}
-
diff --git a/llvm/test/CodeGen/X86/isel-select-cmov.ll b/llvm/test/CodeGen/X86/isel-select-cmov.ll
new file mode 100644
index 000000000000000..755aedc044ca401
--- /dev/null
+++ b/llvm/test/CodeGen/X86/isel-select-cmov.ll
@@ -0,0 +1,455 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -verify-machineinstrs                                                   | FileCheck %s --check-prefix=SDAG-X64
+; RUN: llc < %s -mtriple=x86_64-apple-darwin10 -verify-machineinstrs -mattr=+avx512f                                   | FileCheck %s --check-prefix=SDAG-X64
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 -verify-machineinstrs                     | FileCheck %s --check-prefix=FAST-X64
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=x86_64-apple-darwin10 -verify-machineinstrs -mattr=+avx512f     | FileCheck %s --check-prefix=FAST-X64
+; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=x86_64-apple-darwin10 -verify-machineinstrs                 | FileCheck %s --check-prefix=GISEL-X64
+; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=x86_64-apple-darwin10 -verify-machineinstrs -mattr=+avx512f | FileCheck %s --check-prefix=GISEL-X64
+
+; RUN: llc < %s -mtriple=i686-apple-darwin10 -verify-machineinstrs                                   | FileCheck %s --check-prefix=SDAG-X86
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs     | FileCheck %s --check-prefix=FAST-X86
+; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs | FileCheck %s --check-prefix=GISEL-X86
+
+; Test conditional move for the supported types (i16, i32, and i32) and
+; conditon input (argument or cmp). Currently i8 is not supported.
+
+define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroext %b) {
+; SDAG-X64-LABEL: select_cmov_i16:
+; SDAG-X64:       ## %bb.0:
+; SDAG-X64-NEXT:    movl %esi, %eax
+; SDAG-X64-NEXT:    testl %edi, %edi
+; SDAG-X64-NEXT:    cmovel %edx, %eax
+; SDAG-X64-NEXT:    retq
+;
+; FAST-X64-LABEL: select_cmov_i16:
+; FAST-X64:       ## %bb.0:
+; FAST-X64-NEXT:    testb $1, %dil
+; FAST-X64-NEXT:    cmovew %dx, %si
+; FAST-X64-NEXT:    movzwl %si, %eax
+; FAST-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: select_cmov_i16:
+; GISEL-X64:       ## %bb.0:
+; GISEL-X64-NEXT:    movl %edx, %eax
+; GISEL-X64-NEXT:    andl $1, %edi
+; GISEL-X64-NEXT:    cmovew %si, %ax
+; GISEL-X64-NEXT:    ## kill: def $ax killed $ax killed $eax
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: select_cmov_i16:
+; SDAG-X86:       ## %bb.0:
+; SDAG-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    jne LBB0_1
+; SDAG-X86-NEXT:  ## %bb.2:
+; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movzwl (%eax), %eax
+; SDAG-X86-NEXT:    retl
+; SDAG-X86-NEXT:  LBB0_1:
+; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movzwl (%eax), %eax
+; SDAG-X86-NEXT:    retl
+;
+; FAST-X86-LABEL: select_cmov_i16:
+; FAST-X86:       ## %bb.0:
+; FAST-X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
+; FAST-X86-NEXT:    jne LBB0_1
+; FAST-X86-NEXT:  ## %bb.2:
+; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    movzwl %ax, %eax
+; FAST-X86-NEXT:    retl
+; FAST-X86-NEXT:  LBB0_1:
+; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    movzwl %ax, %eax
+; FAST-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: select_cmov_i16:
+; GISEL-X86:       ## %bb.0:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    andl $1, %eax
+; GISEL-X86-NEXT:    jne LBB0_1
+; GISEL-X86-NEXT:  ## %bb.2:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
+; GISEL-X86-NEXT:    retl
+; GISEL-X86-NEXT:  LBB0_1:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
+; GISEL-X86-NEXT:    retl
+  %1 = select i1 %cond, i16 %a, i16 %b
+  ret i16 %1
+}
+
+define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
+; SDAG-X64-LABEL: select_cmp_cmov_i16:
+; SDAG-X64:       ## %bb.0:
+; SDAG-X64-NEXT:    movl %esi, %eax
+; SDAG-X64-NEXT:    cmpw %ax, %di
+; SDAG-X64-NEXT:    cmovbl %edi, %eax
+; SDAG-X64-NEXT:    retq
+;
+; FAST-X64-LABEL: select_cmp_cmov_i16:
+; FAST-X64:       ## %bb.0:
+; FAST-X64-NEXT:    cmpw %si, %di
+; FAST-X64-NEXT:    cmovbw %di, %si
+; FAST-X64-NEXT:    movzwl %si, %eax
+; FAST-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: select_cmp_cmov_i16:
+; GISEL-X64:       ## %bb.0:
+; GISEL-X64-NEXT:    movl %edi, %eax
+; GISEL-X64-NEXT:    xorl %ecx, %ecx
+; GISEL-X64-NEXT:    cmpw %si, %ax
+; GISEL-X64-NEXT:    setb %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovnew %si, %ax
+; GISEL-X64-NEXT:    ## kill: def $ax killed $ax killed $eax
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: select_cmp_cmov_i16:
+; SDAG-X86:       ## %bb.0:
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    cmpw %cx, %ax
+; SDAG-X86-NEXT:    jb LBB1_2
+; SDAG-X86-NEXT:  ## %bb.1:
+; SDAG-X86-NEXT:    movl %ecx, %eax
+; SDAG-X86-NEXT:  LBB1_2:
+; SDAG-X86-NEXT:    movzwl %ax, %eax
+; SDAG-X86-NEXT:    retl
+;
+; FAST-X86-LABEL: select_cmp_cmov_i16:
+; FAST-X86:       ## %bb.0:
+; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    cmpw %cx, %ax
+; FAST-X86-NEXT:    jb LBB1_2
+; FAST-X86-NEXT:  ## %bb.1:
+; FAST-X86-NEXT:    movl %ecx, %eax
+; FAST-X86-NEXT:  LBB1_2:
+; FAST-X86-NEXT:    movzwl %ax, %eax
+; FAST-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: select_cmp_cmov_i16:
+; GISEL-X86:       ## %bb.0:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    xorl %edx, %edx
+; GISEL-X86-NEXT:    cmpw %ax, %cx
+; GISEL-X86-NEXT:    setb %dl
+; GISEL-X86-NEXT:    andl $1, %edx
+; GISEL-X86-NEXT:    jne LBB1_2
+; GISEL-X86-NEXT:  ## %bb.1:
+; GISEL-X86-NEXT:    movl %ecx, %eax
+; GISEL-X86-NEXT:  LBB1_2:
+; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
+; GISEL-X86-NEXT:    retl
+  %1 = icmp ult i16 %a, %b
+  %2 = select i1 %1, i16 %a, i16 %b
+  ret i16 %2
+}
+
+define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
+; SDAG-X64-LABEL: select_cmov_i32:
+; SDAG-X64:       ## %bb.0:
+; SDAG-X64-NEXT:    movl %esi, %eax
+; SDAG-X64-NEXT:    testl %edi, %edi
+; SDAG-X64-NEXT:    cmovel %edx, %eax
+; SDAG-X64-NEXT:    retq
+;
+; FAST-X64-LABEL: select_cmov_i32:
+; FAST-X64:       ## %bb.0:
+; FAST-X64-NEXT:    movl %esi, %eax
+; FAST-X64-NEXT:    testb $1, %dil
+; FAST-X64-NEXT:    cmovel %edx, %eax
+; FAST-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: select_cmov_i32:
+; GISEL-X64:       ## %bb.0:
+; GISEL-X64-NEXT:    movl %edx, %eax
+; GISEL-X64-NEXT:    andl $1, %edi
+; GISEL-X64-NEXT:    cmovel %esi, %eax
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: select_cmov_i32:
+; SDAG-X86:       ## %bb.0:
+; SDAG-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    jne LBB2_1
+; SDAG-X86-NEXT:  ## %bb.2:
+; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movl (%eax), %eax
+; SDAG-X86-NEXT:    retl
+; SDAG-X86-NEXT:  LBB2_1:
+; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movl (%eax), %eax
+; SDAG-X86-NEXT:    retl
+;
+; FAST-X86-LABEL: select_cmov_i32:
+; FAST-X86:       ## %bb.0:
+; FAST-X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
+; FAST-X86-NEXT:    jne LBB2_1
+; FAST-X86-NEXT:  ## %bb.2:
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    retl
+; FAST-X86-NEXT:  LBB2_1:
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: select_cmov_i32:
+; GISEL-X86:       ## %bb.0:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    andl $1, %eax
+; GISEL-X86-NEXT:    jne LBB2_1
+; GISEL-X86-NEXT:  ## %bb.2:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    retl
+; GISEL-X86-NEXT:  LBB2_1:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    retl
+  %1 = select i1 %cond, i32 %a, i32 %b
+  ret i32 %1
+}
+
+define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
+; SDAG-X64-LABEL: select_cmp_cmov_i32:
+; SDAG-X64:       ## %bb.0:
+; SDAG-X64-NEXT:    movl %esi, %eax
+; SDAG-X64-NEXT:    cmpl %esi, %edi
+; SDAG-X64-NEXT:    cmovbl %edi, %eax
+; SDAG-X64-NEXT:    retq
+;
+; FAST-X64-LABEL: select_cmp_cmov_i32:
+; FAST-X64:       ## %bb.0:
+; FAST-X64-NEXT:    movl %esi, %eax
+; FAST-X64-NEXT:    cmpl %esi, %edi
+; FAST-X64-NEXT:    cmovbl %edi, %eax
+; FAST-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: select_cmp_cmov_i32:
+; GISEL-X64:       ## %bb.0:
+; GISEL-X64-NEXT:    movl %edi, %eax
+; GISEL-X64-NEXT:    xorl %ecx, %ecx
+; GISEL-X64-NEXT:    cmpl %esi, %edi
+; GISEL-X64-NEXT:    setb %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovnel %esi, %eax
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: select_cmp_cmov_i32:
+; SDAG-X86:       ## %bb.0:
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    cmpl %ecx, %eax
+; SDAG-X86-NEXT:    jb LBB3_2
+; SDAG-X86-NEXT:  ## %bb.1:
+; SDAG-X86-NEXT:    movl %ecx, %eax
+; SDAG-X86-NEXT:  LBB3_2:
+; SDAG-X86-NEXT:    retl
+;
+; FAST-X86-LABEL: select_cmp_cmov_i32:
+; FAST-X86:       ## %bb.0:
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    cmpl %ecx, %eax
+; FAST-X86-NEXT:    jb LBB3_2
+; FAST-X86-NEXT:  ## %bb.1:
+; FAST-X86-NEXT:    movl %ecx, %eax
+; FAST-X86-NEXT:  LBB3_2:
+; FAST-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: select_cmp_cmov_i32:
+; GISEL-X86:       ## %bb.0:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    xorl %edx, %edx
+; GISEL-X86-NEXT:    cmpl %eax, %ecx
+; GISEL-X86-NEXT:    setb %dl
+; GISEL-X86-NEXT:    andl $1, %edx
+; GISEL-X86-NEXT:    jne LBB3_2
+; GISEL-X86-NEXT:  ## %bb.1:
+; GISEL-X86-NEXT:    movl %ecx, %eax
+; GISEL-X86-NEXT:  LBB3_2:
+; GISEL-X86-NEXT:    retl
+  %1 = icmp ult i32 %a, %b
+  %2 = select i1 %1, i32 %a, i32 %b
+  ret i32 %2
+}
+
+define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
+; SDAG-X64-LABEL: select_cmov_i64:
+; SDAG-X64:       ## %bb.0:
+; SDAG-X64-NEXT:    movq %rsi, %rax
+; SDAG-X64-NEXT:    testl %edi, %edi
+; SDAG-X64-NEXT:    cmoveq %rdx, %rax
+; SDAG-X64-NEXT:    retq
+;
+; FAST-X64-LABEL: select_cmov_i64:
+; FAST-X64:       ## %bb.0:
+; FAST-X64-NEXT:    movq %rsi, %rax
+; FAST-X64-NEXT:    testb $1, %dil
+; FAST-X64-NEXT:    cmoveq %rdx, %rax
+; FAST-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: select_cmov_i64:
+; GISEL-X64:       ## %bb.0:
+; GISEL-X64-NEXT:    movq %rdx, %rax
+; GISEL-X64-NEXT:    andl $1, %edi
+; GISEL-X64-NEXT:    cmoveq %rsi, %rax
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: select_cmov_i64:
+; SDAG-X86:       ## %bb.0:
+; SDAG-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    jne LBB4_1
+; SDAG-X86-NEXT:  ## %bb.2:
+; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:    jmp LBB4_3
+; SDAG-X86-NEXT:  LBB4_1:
+; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:  LBB4_3:
+; SDAG-X86-NEXT:    movl (%ecx), %eax
+; SDAG-X86-NEXT:    movl 4(%ecx), %edx
+; SDAG-X86-NEXT:    retl
+;
+; FAST-X86-LABEL: select_cmov_i64:
+; FAST-X86:       ## %bb.0:
+; FAST-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; FAST-X86-NEXT:    jne LBB4_1
+; FAST-X86-NEXT:  ## %bb.2:
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    retl
+; FAST-X86-NEXT:  LBB4_1:
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: select_cmov_i64:
+; GISEL-X86:       ## %bb.0:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    andl $1, %ecx
+; GISEL-X86-NEXT:    jne LBB4_1
+; GISEL-X86-NEXT:  ## %bb.2:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    testl %ecx, %ecx
+; GISEL-X86-NEXT:    je LBB4_5
+; GISEL-X86-NEXT:  LBB4_4:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-NEXT:    retl
+; GISEL-X86-NEXT:  LBB4_1:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    testl %ecx, %ecx
+; GISEL-X86-NEXT:    jne LBB4_4
+; GISEL-X86-NEXT:  LBB4_5:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-NEXT:    retl
+  %1 = select i1 %cond, i64 %a, i64 %b
+  ret i64 %1
+}
+
+define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
+; SDAG-X64-LABEL: select_cmp_cmov_i64:
+; SDAG-X64:       ## %bb.0:
+; SDAG-X64-NEXT:    movq %rsi, %rax
+; SDAG-X64-NEXT:    cmpq %rsi, %rdi
+; SDAG-X64-NEXT:    cmovbq %rdi, %rax
+; SDAG-X64-NEXT:    retq
+;
+; FAST-X64-LABEL: select_cmp_cmov_i64:
+; FAST-X64:       ## %bb.0:
+; FAST-X64-NEXT:    movq %rsi, %rax
+; FAST-X64-NEXT:    cmpq %rsi, %rdi
+; FAST-X64-NEXT:    cmovbq %rdi, %rax
+; FAST-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: select_cmp_cmov_i64:
+; GISEL-X64:       ## %bb.0:
+; GISEL-X64-NEXT:    movq %rdi, %rax
+; GISEL-X64-NEXT:    xorl %ecx, %ecx
+; GISEL-X64-NEXT:    cmpq %rsi, %rdi
+; GISEL-X64-NEXT:    setb %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovneq %rsi, %rax
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: select_cmp_cmov_i64:
+; SDAG-X86:       ## %bb.0:
+; SDAG-X86-NEXT:    pushl %edi
+; SDAG-X86-NEXT:    pushl %esi
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; SDAG-X86-NEXT:    cmpl %ecx, %eax
+; SDAG-X86-NEXT:    movl %edx, %edi
+; SDAG-X86-NEXT:    sbbl %esi, %edi
+; SDAG-X86-NEXT:    jb LBB5_2
+; SDAG-X86-NEXT:  ## %bb.1:
+; SDAG-X86-NEXT:    movl %ecx, %eax
+; SDAG-X86-NEXT:    movl %esi, %edx
+; SDAG-X86-NEXT:  LBB5_2:
+; SDAG-X86-NEXT:    popl %esi
+; SDAG-X86-NEXT:    popl %edi
+; SDAG-X86-NEXT:    retl
+;
+; FAST-X86-LABEL: select_cmp_cmov_i64:
+; FAST-X86:       ## %bb.0:
+; FAST-X86-NEXT:    pushl %edi
+; FAST-X86-NEXT:    pushl %esi
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    cmpl %esi, %eax
+; FAST-X86-NEXT:    movl %edx, %edi
+; FAST-X86-NEXT:    sbbl %ecx, %edi
+; FAST-X86-NEXT:    jb LBB5_2
+; FAST-X86-NEXT:  ## %bb.1:
+; FAST-X86-NEXT:    movl %esi, %eax
+; FAST-X86-NEXT:    movl %ecx, %edx
+; FAST-X86-NEXT:  LBB5_2:
+; FAST-X86-NEXT:    popl %esi
+; FAST-X86-NEXT:    popl %edi
+; FAST-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: select_cmp_cmov_i64:
+; GISEL-X86:       ## %bb.0:
+; GISEL-X86-NEXT:    pushl %ebp
+; GISEL-X86-NEXT:    pushl %ebx
+; GISEL-X86-NEXT:    pushl %edi
+; GISEL-X86-NEXT:    pushl %esi
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ebp
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-NEXT:    xorl %ecx, %ecx
+; GISEL-X86-NEXT:    cmpl %edx, %ebp
+; GISEL-X86-NEXT:    setb %bl
+; GISEL-X86-NEXT:    sete %cl
+; GISEL-X86-NEXT:    cmpl %eax, %esi
+; GISEL-X86-NEXT:    setb %bh
+; GISEL-X86-NEXT:    testl %ecx, %ecx
+; GISEL-X86-NEXT:    jne LBB5_2
+; GISEL-X86-NEXT:  ## %bb.1:
+; GISEL-X86-NEXT:    movb %bh, %bl
+; GISEL-X86-NEXT:  LBB5_2:
+; GISEL-X86-NEXT:    movzbl %bl, %edi
+; GISEL-X86-NEXT:    andl $1, %edi
+; GISEL-X86-NEXT:    jne LBB5_4
+; GISEL-X86-NEXT:  ## %bb.3:
+; GISEL-X86-NEXT:    movl %esi, %eax
+; GISEL-X86-NEXT:  LBB5_4:
+; GISEL-X86-NEXT:    testl %edi, %edi
+; GISEL-X86-NEXT:    jne LBB5_6
+; GISEL-X86-NEXT:  ## %bb.5:
+; GISEL-X86-NEXT:    movl %ebp, %edx
+; GISEL-X86-NEXT:  LBB5_6:
+; GISEL-X86-NEXT:    popl %esi
+; GISEL-X86-NEXT:    popl %edi
+; GISEL-X86-NEXT:    popl %ebx
+; GISEL-X86-NEXT:    popl %ebp
+; GISEL-X86-NEXT:    retl
+  %1 = icmp ult i64 %a, %b
+  %2 = select i1 %1, i64 %a, i64 %b
+  ret i64 %2
+}
+

>From 779113a188ded781bbc0fe6ecc929082f362257a Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Fri, 3 Nov 2023 19:38:30 -0700
Subject: [PATCH 2/4] fixup! [X86][GlobalISel] Add instruction selection for
 G_SELECT

---
 .../X86/GISel/X86InstructionSelector.cpp      |  19 +-
 llvm/test/CodeGen/X86/isel-select-cmov.ll     | 169 +++++++++++++-----
 2 files changed, 133 insertions(+), 55 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index b68d22f6c1c3914..be1d7161c677975 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -20,6 +20,7 @@
 #include "X86Subtarget.h"
 #include "X86TargetMachine.h"
 #include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"
+#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h"
 #include "llvm/CodeGen/GlobalISel/Utils.h"
 #include "llvm/CodeGen/LowLevelType.h"
@@ -1796,10 +1797,11 @@ bool X86InstructionSelector::selectMulDivRem(MachineInstr &I,
 bool X86InstructionSelector::selectSelect(MachineInstr &I,
                                           MachineRegisterInfo &MRI,
                                           MachineFunction &MF) const {
-  unsigned DstReg = I.getOperand(0).getReg();
-  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(X86::TEST32rr))
-      .addReg(I.getOperand(1).getReg())
-      .addReg(I.getOperand(1).getReg());
+  GSelect &Sel = cast<GSelect>(I);
+  unsigned DstReg = Sel.getReg(0);
+  BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(X86::TEST32rr))
+      .addReg(Sel.getCondReg())
+      .addReg(Sel.getCondReg());
 
   unsigned OpCmp;
   LLT Ty = MRI.getType(DstReg);
@@ -1820,17 +1822,18 @@ bool X86InstructionSelector::selectSelect(MachineInstr &I,
     OpCmp = X86::CMOV64rr;
     break;
   }
-  BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(OpCmp), DstReg)
-      .addReg(I.getOperand(2).getReg())
-      .addReg(I.getOperand(3).getReg())
+  BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(OpCmp), DstReg)
+      .addReg(Sel.getTrueReg())
+      .addReg(Sel.getFalseReg())
       .addImm(5);
+
   const TargetRegisterClass *DstRC = getRegClass(Ty, DstReg, MRI);
   if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
     LLVM_DEBUG(dbgs() << "Failed to constrain CMOV\n");
     return false;
   }
 
-  I.eraseFromParent();
+  Sel.eraseFromParent();
   return true;
 }
 
diff --git a/llvm/test/CodeGen/X86/isel-select-cmov.ll b/llvm/test/CodeGen/X86/isel-select-cmov.ll
index 755aedc044ca401..156b3d121168ea9 100644
--- a/llvm/test/CodeGen/X86/isel-select-cmov.ll
+++ b/llvm/test/CodeGen/X86/isel-select-cmov.ll
@@ -11,7 +11,82 @@
 ; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs | FileCheck %s --check-prefix=GISEL-X86
 
 ; Test conditional move for the supported types (i16, i32, and i32) and
-; conditon input (argument or cmp). Currently i8 is not supported.
+; conditon input (argument or cmp).
+; When cmov is not available (i8 type or X86), the branch is expected.
+
+define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b) {
+; SDAG-X64-LABEL: select_cmov_i8:
+; SDAG-X64:       ## %bb.0:
+; SDAG-X64-NEXT:    movl %esi, %eax
+; SDAG-X64-NEXT:    testl %edi, %edi
+; SDAG-X64-NEXT:    cmovel %edx, %eax
+; SDAG-X64-NEXT:    retq
+;
+; FAST-X64-LABEL: select_cmov_i8:
+; FAST-X64:       ## %bb.0:
+; FAST-X64-NEXT:    testb $1, %dil
+; FAST-X64-NEXT:    jne LBB0_2
+; FAST-X64-NEXT:  ## %bb.1:
+; FAST-X64-NEXT:    movl %edx, %esi
+; FAST-X64-NEXT:  LBB0_2:
+; FAST-X64-NEXT:    movzbl %sil, %eax
+; FAST-X64-NEXT:    retq
+;
+; GISEL-X64-LABEL: select_cmov_i8:
+; GISEL-X64:       ## %bb.0:
+; GISEL-X64-NEXT:    andl $1, %edi
+; GISEL-X64-NEXT:    jne LBB0_1
+; GISEL-X64-NEXT:  ## %bb.2:
+; GISEL-X64-NEXT:    movl %esi, %eax
+; GISEL-X64-NEXT:    ## kill: def $al killed $al killed $eax
+; GISEL-X64-NEXT:    retq
+; GISEL-X64-NEXT:  LBB0_1:
+; GISEL-X64-NEXT:    movl %edx, %eax
+; GISEL-X64-NEXT:    ## kill: def $al killed $al killed $eax
+; GISEL-X64-NEXT:    retq
+;
+; SDAG-X86-LABEL: select_cmov_i8:
+; SDAG-X86:       ## %bb.0:
+; SDAG-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; SDAG-X86-NEXT:    jne LBB0_1
+; SDAG-X86-NEXT:  ## %bb.2:
+; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movzbl (%eax), %eax
+; SDAG-X86-NEXT:    retl
+; SDAG-X86-NEXT:  LBB0_1:
+; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-NEXT:    movzbl (%eax), %eax
+; SDAG-X86-NEXT:    retl
+;
+; FAST-X86-LABEL: select_cmov_i8:
+; FAST-X86:       ## %bb.0:
+; FAST-X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
+; FAST-X86-NEXT:    jne LBB0_1
+; FAST-X86-NEXT:  ## %bb.2:
+; FAST-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    movzbl %al, %eax
+; FAST-X86-NEXT:    retl
+; FAST-X86-NEXT:  LBB0_1:
+; FAST-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; FAST-X86-NEXT:    movzbl %al, %eax
+; FAST-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: select_cmov_i8:
+; GISEL-X86:       ## %bb.0:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    andl $1, %eax
+; GISEL-X86-NEXT:    jne LBB0_1
+; GISEL-X86-NEXT:  ## %bb.2:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    ## kill: def $al killed $al killed $eax
+; GISEL-X86-NEXT:    retl
+; GISEL-X86-NEXT:  LBB0_1:
+; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    ## kill: def $al killed $al killed $eax
+; GISEL-X86-NEXT:    retl
+  %1 = select i1 %cond, i8 %a, i8 %b
+  ret i8 %1
+}
 
 define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroext %b) {
 ; SDAG-X64-LABEL: select_cmov_i16:
@@ -39,12 +114,12 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
 ; SDAG-X86-LABEL: select_cmov_i16:
 ; SDAG-X86:       ## %bb.0:
 ; SDAG-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    jne LBB0_1
+; SDAG-X86-NEXT:    jne LBB1_1
 ; SDAG-X86-NEXT:  ## %bb.2:
 ; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    movzwl (%eax), %eax
 ; SDAG-X86-NEXT:    retl
-; SDAG-X86-NEXT:  LBB0_1:
+; SDAG-X86-NEXT:  LBB1_1:
 ; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    movzwl (%eax), %eax
 ; SDAG-X86-NEXT:    retl
@@ -52,12 +127,12 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
 ; FAST-X86-LABEL: select_cmov_i16:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; FAST-X86-NEXT:    jne LBB0_1
+; FAST-X86-NEXT:    jne LBB1_1
 ; FAST-X86-NEXT:  ## %bb.2:
 ; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    movzwl %ax, %eax
 ; FAST-X86-NEXT:    retl
-; FAST-X86-NEXT:  LBB0_1:
+; FAST-X86-NEXT:  LBB1_1:
 ; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    movzwl %ax, %eax
 ; FAST-X86-NEXT:    retl
@@ -66,12 +141,12 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    andl $1, %eax
-; GISEL-X86-NEXT:    jne LBB0_1
+; GISEL-X86-NEXT:    jne LBB1_1
 ; GISEL-X86-NEXT:  ## %bb.2:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
 ; GISEL-X86-NEXT:    retl
-; GISEL-X86-NEXT:  LBB0_1:
+; GISEL-X86-NEXT:  LBB1_1:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
 ; GISEL-X86-NEXT:    retl
@@ -110,10 +185,10 @@ define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    cmpw %cx, %ax
-; SDAG-X86-NEXT:    jb LBB1_2
+; SDAG-X86-NEXT:    jb LBB2_2
 ; SDAG-X86-NEXT:  ## %bb.1:
 ; SDAG-X86-NEXT:    movl %ecx, %eax
-; SDAG-X86-NEXT:  LBB1_2:
+; SDAG-X86-NEXT:  LBB2_2:
 ; SDAG-X86-NEXT:    movzwl %ax, %eax
 ; SDAG-X86-NEXT:    retl
 ;
@@ -122,10 +197,10 @@ define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
 ; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
 ; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    cmpw %cx, %ax
-; FAST-X86-NEXT:    jb LBB1_2
+; FAST-X86-NEXT:    jb LBB2_2
 ; FAST-X86-NEXT:  ## %bb.1:
 ; FAST-X86-NEXT:    movl %ecx, %eax
-; FAST-X86-NEXT:  LBB1_2:
+; FAST-X86-NEXT:  LBB2_2:
 ; FAST-X86-NEXT:    movzwl %ax, %eax
 ; FAST-X86-NEXT:    retl
 ;
@@ -137,10 +212,10 @@ define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
 ; GISEL-X86-NEXT:    cmpw %ax, %cx
 ; GISEL-X86-NEXT:    setb %dl
 ; GISEL-X86-NEXT:    andl $1, %edx
-; GISEL-X86-NEXT:    jne LBB1_2
+; GISEL-X86-NEXT:    jne LBB2_2
 ; GISEL-X86-NEXT:  ## %bb.1:
 ; GISEL-X86-NEXT:    movl %ecx, %eax
-; GISEL-X86-NEXT:  LBB1_2:
+; GISEL-X86-NEXT:  LBB2_2:
 ; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
 ; GISEL-X86-NEXT:    retl
   %1 = icmp ult i16 %a, %b
@@ -173,12 +248,12 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
 ; SDAG-X86-LABEL: select_cmov_i32:
 ; SDAG-X86:       ## %bb.0:
 ; SDAG-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    jne LBB2_1
+; SDAG-X86-NEXT:    jne LBB3_1
 ; SDAG-X86-NEXT:  ## %bb.2:
 ; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    movl (%eax), %eax
 ; SDAG-X86-NEXT:    retl
-; SDAG-X86-NEXT:  LBB2_1:
+; SDAG-X86-NEXT:  LBB3_1:
 ; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    movl (%eax), %eax
 ; SDAG-X86-NEXT:    retl
@@ -186,11 +261,11 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
 ; FAST-X86-LABEL: select_cmov_i32:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
-; FAST-X86-NEXT:    jne LBB2_1
+; FAST-X86-NEXT:    jne LBB3_1
 ; FAST-X86-NEXT:  ## %bb.2:
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    retl
-; FAST-X86-NEXT:  LBB2_1:
+; FAST-X86-NEXT:  LBB3_1:
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    retl
 ;
@@ -198,11 +273,11 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    andl $1, %eax
-; GISEL-X86-NEXT:    jne LBB2_1
+; GISEL-X86-NEXT:    jne LBB3_1
 ; GISEL-X86-NEXT:  ## %bb.2:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    retl
-; GISEL-X86-NEXT:  LBB2_1:
+; GISEL-X86-NEXT:  LBB3_1:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    retl
   %1 = select i1 %cond, i32 %a, i32 %b
@@ -239,10 +314,10 @@ define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; SDAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; SDAG-X86-NEXT:    cmpl %ecx, %eax
-; SDAG-X86-NEXT:    jb LBB3_2
+; SDAG-X86-NEXT:    jb LBB4_2
 ; SDAG-X86-NEXT:  ## %bb.1:
 ; SDAG-X86-NEXT:    movl %ecx, %eax
-; SDAG-X86-NEXT:  LBB3_2:
+; SDAG-X86-NEXT:  LBB4_2:
 ; SDAG-X86-NEXT:    retl
 ;
 ; FAST-X86-LABEL: select_cmp_cmov_i32:
@@ -250,10 +325,10 @@ define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    cmpl %ecx, %eax
-; FAST-X86-NEXT:    jb LBB3_2
+; FAST-X86-NEXT:    jb LBB4_2
 ; FAST-X86-NEXT:  ## %bb.1:
 ; FAST-X86-NEXT:    movl %ecx, %eax
-; FAST-X86-NEXT:  LBB3_2:
+; FAST-X86-NEXT:  LBB4_2:
 ; FAST-X86-NEXT:    retl
 ;
 ; GISEL-X86-LABEL: select_cmp_cmov_i32:
@@ -264,10 +339,10 @@ define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
 ; GISEL-X86-NEXT:    cmpl %eax, %ecx
 ; GISEL-X86-NEXT:    setb %dl
 ; GISEL-X86-NEXT:    andl $1, %edx
-; GISEL-X86-NEXT:    jne LBB3_2
+; GISEL-X86-NEXT:    jne LBB4_2
 ; GISEL-X86-NEXT:  ## %bb.1:
 ; GISEL-X86-NEXT:    movl %ecx, %eax
-; GISEL-X86-NEXT:  LBB3_2:
+; GISEL-X86-NEXT:  LBB4_2:
 ; GISEL-X86-NEXT:    retl
   %1 = icmp ult i32 %a, %b
   %2 = select i1 %1, i32 %a, i32 %b
@@ -299,13 +374,13 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
 ; SDAG-X86-LABEL: select_cmov_i64:
 ; SDAG-X86:       ## %bb.0:
 ; SDAG-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
-; SDAG-X86-NEXT:    jne LBB4_1
+; SDAG-X86-NEXT:    jne LBB5_1
 ; SDAG-X86-NEXT:  ## %bb.2:
 ; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
-; SDAG-X86-NEXT:    jmp LBB4_3
-; SDAG-X86-NEXT:  LBB4_1:
+; SDAG-X86-NEXT:    jmp LBB5_3
+; SDAG-X86-NEXT:  LBB5_1:
 ; SDAG-X86-NEXT:    leal {{[0-9]+}}(%esp), %ecx
-; SDAG-X86-NEXT:  LBB4_3:
+; SDAG-X86-NEXT:  LBB5_3:
 ; SDAG-X86-NEXT:    movl (%ecx), %eax
 ; SDAG-X86-NEXT:    movl 4(%ecx), %edx
 ; SDAG-X86-NEXT:    retl
@@ -313,12 +388,12 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
 ; FAST-X86-LABEL: select_cmov_i64:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
-; FAST-X86-NEXT:    jne LBB4_1
+; FAST-X86-NEXT:    jne LBB5_1
 ; FAST-X86-NEXT:  ## %bb.2:
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    retl
-; FAST-X86-NEXT:  LBB4_1:
+; FAST-X86-NEXT:  LBB5_1:
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    retl
@@ -327,19 +402,19 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; GISEL-X86-NEXT:    andl $1, %ecx
-; GISEL-X86-NEXT:    jne LBB4_1
+; GISEL-X86-NEXT:    jne LBB5_1
 ; GISEL-X86-NEXT:  ## %bb.2:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    testl %ecx, %ecx
-; GISEL-X86-NEXT:    je LBB4_5
-; GISEL-X86-NEXT:  LBB4_4:
+; GISEL-X86-NEXT:    je LBB5_5
+; GISEL-X86-NEXT:  LBB5_4:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; GISEL-X86-NEXT:    retl
-; GISEL-X86-NEXT:  LBB4_1:
+; GISEL-X86-NEXT:  LBB5_1:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    testl %ecx, %ecx
-; GISEL-X86-NEXT:    jne LBB4_4
-; GISEL-X86-NEXT:  LBB4_5:
+; GISEL-X86-NEXT:    jne LBB5_4
+; GISEL-X86-NEXT:  LBB5_5:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; GISEL-X86-NEXT:    retl
   %1 = select i1 %cond, i64 %a, i64 %b
@@ -382,11 +457,11 @@ define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
 ; SDAG-X86-NEXT:    cmpl %ecx, %eax
 ; SDAG-X86-NEXT:    movl %edx, %edi
 ; SDAG-X86-NEXT:    sbbl %esi, %edi
-; SDAG-X86-NEXT:    jb LBB5_2
+; SDAG-X86-NEXT:    jb LBB6_2
 ; SDAG-X86-NEXT:  ## %bb.1:
 ; SDAG-X86-NEXT:    movl %ecx, %eax
 ; SDAG-X86-NEXT:    movl %esi, %edx
-; SDAG-X86-NEXT:  LBB5_2:
+; SDAG-X86-NEXT:  LBB6_2:
 ; SDAG-X86-NEXT:    popl %esi
 ; SDAG-X86-NEXT:    popl %edi
 ; SDAG-X86-NEXT:    retl
@@ -402,11 +477,11 @@ define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
 ; FAST-X86-NEXT:    cmpl %esi, %eax
 ; FAST-X86-NEXT:    movl %edx, %edi
 ; FAST-X86-NEXT:    sbbl %ecx, %edi
-; FAST-X86-NEXT:    jb LBB5_2
+; FAST-X86-NEXT:    jb LBB6_2
 ; FAST-X86-NEXT:  ## %bb.1:
 ; FAST-X86-NEXT:    movl %esi, %eax
 ; FAST-X86-NEXT:    movl %ecx, %edx
-; FAST-X86-NEXT:  LBB5_2:
+; FAST-X86-NEXT:  LBB6_2:
 ; FAST-X86-NEXT:    popl %esi
 ; FAST-X86-NEXT:    popl %edi
 ; FAST-X86-NEXT:    retl
@@ -428,21 +503,21 @@ define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
 ; GISEL-X86-NEXT:    cmpl %eax, %esi
 ; GISEL-X86-NEXT:    setb %bh
 ; GISEL-X86-NEXT:    testl %ecx, %ecx
-; GISEL-X86-NEXT:    jne LBB5_2
+; GISEL-X86-NEXT:    jne LBB6_2
 ; GISEL-X86-NEXT:  ## %bb.1:
 ; GISEL-X86-NEXT:    movb %bh, %bl
-; GISEL-X86-NEXT:  LBB5_2:
+; GISEL-X86-NEXT:  LBB6_2:
 ; GISEL-X86-NEXT:    movzbl %bl, %edi
 ; GISEL-X86-NEXT:    andl $1, %edi
-; GISEL-X86-NEXT:    jne LBB5_4
+; GISEL-X86-NEXT:    jne LBB6_4
 ; GISEL-X86-NEXT:  ## %bb.3:
 ; GISEL-X86-NEXT:    movl %esi, %eax
-; GISEL-X86-NEXT:  LBB5_4:
+; GISEL-X86-NEXT:  LBB6_4:
 ; GISEL-X86-NEXT:    testl %edi, %edi
-; GISEL-X86-NEXT:    jne LBB5_6
+; GISEL-X86-NEXT:    jne LBB6_6
 ; GISEL-X86-NEXT:  ## %bb.5:
 ; GISEL-X86-NEXT:    movl %ebp, %edx
-; GISEL-X86-NEXT:  LBB5_6:
+; GISEL-X86-NEXT:  LBB6_6:
 ; GISEL-X86-NEXT:    popl %esi
 ; GISEL-X86-NEXT:    popl %edi
 ; GISEL-X86-NEXT:    popl %ebx

>From 29b3c67715a87541cac5e99099d648c0969f083c Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Mon, 6 Nov 2023 18:35:45 -0800
Subject: [PATCH 3/4] fixup! fixup! [X86][GlobalISel] Add instruction selection
 for G_SELECT

---
 .../X86/GISel/X86InstructionSelector.cpp      |  2 +-
 .../lib/Target/X86/GISel/X86LegalizerInfo.cpp |  3 +-
 .../X86/GlobalISel/legalize-select.mir        | 29 +++++++++----
 llvm/test/CodeGen/X86/isel-select-cmov.ll     | 43 ++++++++-----------
 4 files changed, 43 insertions(+), 34 deletions(-)

diff --git a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
index be1d7161c677975..d7a10f45cb5f132 100644
--- a/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
+++ b/llvm/lib/Target/X86/GISel/X86InstructionSelector.cpp
@@ -1825,7 +1825,7 @@ bool X86InstructionSelector::selectSelect(MachineInstr &I,
   BuildMI(*Sel.getParent(), Sel, Sel.getDebugLoc(), TII.get(OpCmp), DstReg)
       .addReg(Sel.getTrueReg())
       .addReg(Sel.getFalseReg())
-      .addImm(5);
+      .addImm(X86::COND_E);
 
   const TargetRegisterClass *DstRC = getRegClass(Ty, DstReg, MRI);
   if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index 0e4a656838a4a94..27381dff338e2d5 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -29,6 +29,7 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
     : Subtarget(STI) {
 
   bool Is64Bit = Subtarget.is64Bit();
+  bool HasCMOV = Subtarget.canUseCMOV();
   bool HasSSE1 = Subtarget.hasSSE1();
   bool HasSSE2 = Subtarget.hasSSE2();
   bool HasSSE41 = Subtarget.hasSSE41();
@@ -523,7 +524,7 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
   getActionDefinitionsBuilder(G_SELECT)
       .legalFor({{s8, s32}, {s16, s32}, {s32, s32}, {s64, s32}, {p0, s32}})
       .widenScalarToNextPow2(0, /*Min=*/8)
-      .clampScalar(0, s8, sMaxScalar)
+      .clampScalar(0, HasCMOV ? s16 : s8, sMaxScalar)
       .clampScalar(1, s32, s32);
 
   // memory intrinsics
diff --git a/llvm/test/CodeGen/X86/GlobalISel/legalize-select.mir b/llvm/test/CodeGen/X86/GlobalISel/legalize-select.mir
index 1a29014246d3cc8..a7cbb35e3f74c2c 100644
--- a/llvm/test/CodeGen/X86/GlobalISel/legalize-select.mir
+++ b/llvm/test/CodeGen/X86/GlobalISel/legalize-select.mir
@@ -41,6 +41,7 @@ body:             |
     ; X86-NEXT: [[MV:%[0-9]+]]:_(s64) = G_MERGE_VALUES [[SELECT]](s32), [[SELECT1]](s32)
     ; X86-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY [[MV]](s64)
     ; X86-NEXT: RET 0, implicit [[COPY]](s64)
+    ;
     ; X64-LABEL: name: test_select64
     ; X64: [[DEF:%[0-9]+]]:_(s64) = IMPLICIT_DEF
     ; X64-NEXT: [[DEF1:%[0-9]+]]:_(s64) = IMPLICIT_DEF
@@ -101,14 +102,26 @@ body:             |
 name:            test_select8
 body:             |
   bb.1:
-    ; CHECK-LABEL: name: test_select8
-    ; CHECK: [[DEF:%[0-9]+]]:_(s8) = IMPLICIT_DEF
-    ; CHECK-NEXT: [[DEF1:%[0-9]+]]:_(s8) = IMPLICIT_DEF
-    ; CHECK-NEXT: [[DEF2:%[0-9]+]]:_(s1) = IMPLICIT_DEF
-    ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[DEF2]](s1)
-    ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s8) = G_SELECT [[ZEXT]](s32), [[DEF1]], [[DEF]]
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s8) = COPY [[SELECT]](s8)
-    ; CHECK-NEXT: RET 0, implicit [[COPY]](s8)
+    ; X86-LABEL: name: test_select8
+    ; X86: [[DEF:%[0-9]+]]:_(s8) = IMPLICIT_DEF
+    ; X86-NEXT: [[DEF1:%[0-9]+]]:_(s8) = IMPLICIT_DEF
+    ; X86-NEXT: [[DEF2:%[0-9]+]]:_(s1) = IMPLICIT_DEF
+    ; X86-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[DEF2]](s1)
+    ; X86-NEXT: [[SELECT:%[0-9]+]]:_(s8) = G_SELECT [[ZEXT]](s32), [[DEF1]], [[DEF]]
+    ; X86-NEXT: [[COPY:%[0-9]+]]:_(s8) = COPY [[SELECT]](s8)
+    ; X86-NEXT: RET 0, implicit [[COPY]](s8)
+    ;
+    ; X64-LABEL: name: test_select8
+    ; X64: [[DEF:%[0-9]+]]:_(s8) = IMPLICIT_DEF
+    ; X64-NEXT: [[DEF1:%[0-9]+]]:_(s8) = IMPLICIT_DEF
+    ; X64-NEXT: [[DEF2:%[0-9]+]]:_(s1) = IMPLICIT_DEF
+    ; X64-NEXT: [[ANYEXT:%[0-9]+]]:_(s16) = G_ANYEXT [[DEF1]](s8)
+    ; X64-NEXT: [[ANYEXT1:%[0-9]+]]:_(s16) = G_ANYEXT [[DEF]](s8)
+    ; X64-NEXT: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[DEF2]](s1)
+    ; X64-NEXT: [[SELECT:%[0-9]+]]:_(s16) = G_SELECT [[ZEXT]](s32), [[ANYEXT]], [[ANYEXT1]]
+    ; X64-NEXT: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[SELECT]](s16)
+    ; X64-NEXT: [[COPY:%[0-9]+]]:_(s8) = COPY [[TRUNC]](s8)
+    ; X64-NEXT: RET 0, implicit [[COPY]](s8)
     %0:_(s8) = IMPLICIT_DEF
     %1:_(s8) = IMPLICIT_DEF
     %2:_(s1) = IMPLICIT_DEF
diff --git a/llvm/test/CodeGen/X86/isel-select-cmov.ll b/llvm/test/CodeGen/X86/isel-select-cmov.ll
index 156b3d121168ea9..d83f532990aa06a 100644
--- a/llvm/test/CodeGen/X86/isel-select-cmov.ll
+++ b/llvm/test/CodeGen/X86/isel-select-cmov.ll
@@ -34,14 +34,9 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b
 ;
 ; GISEL-X64-LABEL: select_cmov_i8:
 ; GISEL-X64:       ## %bb.0:
-; GISEL-X64-NEXT:    andl $1, %edi
-; GISEL-X64-NEXT:    jne LBB0_1
-; GISEL-X64-NEXT:  ## %bb.2:
-; GISEL-X64-NEXT:    movl %esi, %eax
-; GISEL-X64-NEXT:    ## kill: def $al killed $al killed $eax
-; GISEL-X64-NEXT:    retq
-; GISEL-X64-NEXT:  LBB0_1:
 ; GISEL-X64-NEXT:    movl %edx, %eax
+; GISEL-X64-NEXT:    andl $1, %edi
+; GISEL-X64-NEXT:    cmovnew %si, %ax
 ; GISEL-X64-NEXT:    ## kill: def $al killed $al killed $eax
 ; GISEL-X64-NEXT:    retq
 ;
@@ -75,7 +70,7 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    andl $1, %eax
-; GISEL-X86-NEXT:    jne LBB0_1
+; GISEL-X86-NEXT:    je LBB0_1
 ; GISEL-X86-NEXT:  ## %bb.2:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    ## kill: def $al killed $al killed $eax
@@ -107,7 +102,7 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
 ; GISEL-X64:       ## %bb.0:
 ; GISEL-X64-NEXT:    movl %edx, %eax
 ; GISEL-X64-NEXT:    andl $1, %edi
-; GISEL-X64-NEXT:    cmovew %si, %ax
+; GISEL-X64-NEXT:    cmovnew %si, %ax
 ; GISEL-X64-NEXT:    ## kill: def $ax killed $ax killed $eax
 ; GISEL-X64-NEXT:    retq
 ;
@@ -141,7 +136,7 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    andl $1, %eax
-; GISEL-X86-NEXT:    jne LBB1_1
+; GISEL-X86-NEXT:    je LBB1_1
 ; GISEL-X86-NEXT:  ## %bb.2:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
@@ -176,7 +171,7 @@ define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
 ; GISEL-X64-NEXT:    cmpw %si, %ax
 ; GISEL-X64-NEXT:    setb %cl
 ; GISEL-X64-NEXT:    andl $1, %ecx
-; GISEL-X64-NEXT:    cmovnew %si, %ax
+; GISEL-X64-NEXT:    cmovew %si, %ax
 ; GISEL-X64-NEXT:    ## kill: def $ax killed $ax killed $eax
 ; GISEL-X64-NEXT:    retq
 ;
@@ -212,7 +207,7 @@ define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
 ; GISEL-X86-NEXT:    cmpw %ax, %cx
 ; GISEL-X86-NEXT:    setb %dl
 ; GISEL-X86-NEXT:    andl $1, %edx
-; GISEL-X86-NEXT:    jne LBB2_2
+; GISEL-X86-NEXT:    je LBB2_2
 ; GISEL-X86-NEXT:  ## %bb.1:
 ; GISEL-X86-NEXT:    movl %ecx, %eax
 ; GISEL-X86-NEXT:  LBB2_2:
@@ -242,7 +237,7 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
 ; GISEL-X64:       ## %bb.0:
 ; GISEL-X64-NEXT:    movl %edx, %eax
 ; GISEL-X64-NEXT:    andl $1, %edi
-; GISEL-X64-NEXT:    cmovel %esi, %eax
+; GISEL-X64-NEXT:    cmovnel %esi, %eax
 ; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: select_cmov_i32:
@@ -273,7 +268,7 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    andl $1, %eax
-; GISEL-X86-NEXT:    jne LBB3_1
+; GISEL-X86-NEXT:    je LBB3_1
 ; GISEL-X86-NEXT:  ## %bb.2:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    retl
@@ -306,7 +301,7 @@ define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
 ; GISEL-X64-NEXT:    cmpl %esi, %edi
 ; GISEL-X64-NEXT:    setb %cl
 ; GISEL-X64-NEXT:    andl $1, %ecx
-; GISEL-X64-NEXT:    cmovnel %esi, %eax
+; GISEL-X64-NEXT:    cmovel %esi, %eax
 ; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: select_cmp_cmov_i32:
@@ -339,7 +334,7 @@ define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
 ; GISEL-X86-NEXT:    cmpl %eax, %ecx
 ; GISEL-X86-NEXT:    setb %dl
 ; GISEL-X86-NEXT:    andl $1, %edx
-; GISEL-X86-NEXT:    jne LBB4_2
+; GISEL-X86-NEXT:    je LBB4_2
 ; GISEL-X86-NEXT:  ## %bb.1:
 ; GISEL-X86-NEXT:    movl %ecx, %eax
 ; GISEL-X86-NEXT:  LBB4_2:
@@ -368,7 +363,7 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
 ; GISEL-X64:       ## %bb.0:
 ; GISEL-X64-NEXT:    movq %rdx, %rax
 ; GISEL-X64-NEXT:    andl $1, %edi
-; GISEL-X64-NEXT:    cmoveq %rsi, %rax
+; GISEL-X64-NEXT:    cmovneq %rsi, %rax
 ; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: select_cmov_i64:
@@ -402,18 +397,18 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
 ; GISEL-X86-NEXT:    andl $1, %ecx
-; GISEL-X86-NEXT:    jne LBB5_1
+; GISEL-X86-NEXT:    je LBB5_1
 ; GISEL-X86-NEXT:  ## %bb.2:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    testl %ecx, %ecx
-; GISEL-X86-NEXT:    je LBB5_5
+; GISEL-X86-NEXT:    jne LBB5_5
 ; GISEL-X86-NEXT:  LBB5_4:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; GISEL-X86-NEXT:    retl
 ; GISEL-X86-NEXT:  LBB5_1:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    testl %ecx, %ecx
-; GISEL-X86-NEXT:    jne LBB5_4
+; GISEL-X86-NEXT:    je LBB5_4
 ; GISEL-X86-NEXT:  LBB5_5:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; GISEL-X86-NEXT:    retl
@@ -443,7 +438,7 @@ define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
 ; GISEL-X64-NEXT:    cmpq %rsi, %rdi
 ; GISEL-X64-NEXT:    setb %cl
 ; GISEL-X64-NEXT:    andl $1, %ecx
-; GISEL-X64-NEXT:    cmovneq %rsi, %rax
+; GISEL-X64-NEXT:    cmoveq %rsi, %rax
 ; GISEL-X64-NEXT:    retq
 ;
 ; SDAG-X86-LABEL: select_cmp_cmov_i64:
@@ -503,18 +498,18 @@ define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
 ; GISEL-X86-NEXT:    cmpl %eax, %esi
 ; GISEL-X86-NEXT:    setb %bh
 ; GISEL-X86-NEXT:    testl %ecx, %ecx
-; GISEL-X86-NEXT:    jne LBB6_2
+; GISEL-X86-NEXT:    je LBB6_2
 ; GISEL-X86-NEXT:  ## %bb.1:
 ; GISEL-X86-NEXT:    movb %bh, %bl
 ; GISEL-X86-NEXT:  LBB6_2:
 ; GISEL-X86-NEXT:    movzbl %bl, %edi
 ; GISEL-X86-NEXT:    andl $1, %edi
-; GISEL-X86-NEXT:    jne LBB6_4
+; GISEL-X86-NEXT:    je LBB6_4
 ; GISEL-X86-NEXT:  ## %bb.3:
 ; GISEL-X86-NEXT:    movl %esi, %eax
 ; GISEL-X86-NEXT:  LBB6_4:
 ; GISEL-X86-NEXT:    testl %edi, %edi
-; GISEL-X86-NEXT:    jne LBB6_6
+; GISEL-X86-NEXT:    je LBB6_6
 ; GISEL-X86-NEXT:  ## %bb.5:
 ; GISEL-X86-NEXT:    movl %ebp, %edx
 ; GISEL-X86-NEXT:  LBB6_6:

>From 332aa69e319b1e7b2deebbaad30db914ccdcf9c8 Mon Sep 17 00:00:00 2001
From: Evgenii Kudriashov <evgenii.kudriashov at intel.com>
Date: Mon, 13 Nov 2023 15:41:54 -0800
Subject: [PATCH 4/4] fixup! fixup! fixup! [X86][GlobalISel] Add instruction
 selection for G_SELECT

---
 llvm/test/CodeGen/X86/isel-select-cmov.ll | 242 +++++++++++++++++++++-
 1 file changed, 239 insertions(+), 3 deletions(-)

diff --git a/llvm/test/CodeGen/X86/isel-select-cmov.ll b/llvm/test/CodeGen/X86/isel-select-cmov.ll
index d83f532990aa06a..679d9b0ddd49c3f 100644
--- a/llvm/test/CodeGen/X86/isel-select-cmov.ll
+++ b/llvm/test/CodeGen/X86/isel-select-cmov.ll
@@ -6,9 +6,12 @@
 ; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=x86_64-apple-darwin10 -verify-machineinstrs                 | FileCheck %s --check-prefix=GISEL-X64
 ; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=x86_64-apple-darwin10 -verify-machineinstrs -mattr=+avx512f | FileCheck %s --check-prefix=GISEL-X64
 
-; RUN: llc < %s -mtriple=i686-apple-darwin10 -verify-machineinstrs                                   | FileCheck %s --check-prefix=SDAG-X86
-; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs     | FileCheck %s --check-prefix=FAST-X86
-; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs | FileCheck %s --check-prefix=GISEL-X86
+; RUN: llc < %s -mtriple=i686-apple-darwin10 -verify-machineinstrs                                                | FileCheck %s --check-prefix=SDAG-X86
+; RUN: llc < %s -mtriple=i686-apple-darwin10 -verify-machineinstrs -mattr=+cmov                                   | FileCheck %s --check-prefix=SDAG-X86-CMOV
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs                  | FileCheck %s --check-prefix=FAST-X86
+; RUN: llc < %s -fast-isel -fast-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs -mattr=+cmov     | FileCheck %s --check-prefix=FAST-X86-CMOV
+; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs              | FileCheck %s --check-prefix=GISEL-X86
+; RUN: llc < %s -global-isel -global-isel-abort=1 -mtriple=i686-apple-darwin10 -verify-machineinstrs -mattr=+cmov | FileCheck %s --check-prefix=GISEL-X86-CMOV
 
 ; Test conditional move for the supported types (i16, i32, and i32) and
 ; conditon input (argument or cmp).
@@ -53,6 +56,15 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b
 ; SDAG-X86-NEXT:    movzbl (%eax), %eax
 ; SDAG-X86-NEXT:    retl
 ;
+; SDAG-X86-CMOV-LABEL: select_cmov_i8:
+; SDAG-X86-CMOV:       ## %bb.0:
+; SDAG-X86-CMOV-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; SDAG-X86-CMOV-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-CMOV-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-CMOV-NEXT:    cmovnel %eax, %ecx
+; SDAG-X86-CMOV-NEXT:    movzbl (%ecx), %eax
+; SDAG-X86-CMOV-NEXT:    retl
+;
 ; FAST-X86-LABEL: select_cmov_i8:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
@@ -66,6 +78,19 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b
 ; FAST-X86-NEXT:    movzbl %al, %eax
 ; FAST-X86-NEXT:    retl
 ;
+; FAST-X86-CMOV-LABEL: select_cmov_i8:
+; FAST-X86-CMOV:       ## %bb.0:
+; FAST-X86-CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
+; FAST-X86-CMOV-NEXT:    jne LBB0_1
+; FAST-X86-CMOV-NEXT:  ## %bb.2:
+; FAST-X86-CMOV-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    movzbl %al, %eax
+; FAST-X86-CMOV-NEXT:    retl
+; FAST-X86-CMOV-NEXT:  LBB0_1:
+; FAST-X86-CMOV-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    movzbl %al, %eax
+; FAST-X86-CMOV-NEXT:    retl
+;
 ; GISEL-X86-LABEL: select_cmov_i8:
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -79,6 +104,16 @@ define zeroext i8 @select_cmov_i8(i1 zeroext %cond, i8 zeroext %a, i8 zeroext %b
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    ## kill: def $al killed $al killed $eax
 ; GISEL-X86-NEXT:    retl
+;
+; GISEL-X86-CMOV-LABEL: select_cmov_i8:
+; GISEL-X86-CMOV:       ## %bb.0:
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-CMOV-NEXT:    andl $1, %ecx
+; GISEL-X86-CMOV-NEXT:    cmovnew %dx, %ax
+; GISEL-X86-CMOV-NEXT:    ## kill: def $al killed $al killed $eax
+; GISEL-X86-CMOV-NEXT:    retl
   %1 = select i1 %cond, i8 %a, i8 %b
   ret i8 %1
 }
@@ -119,6 +154,15 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
 ; SDAG-X86-NEXT:    movzwl (%eax), %eax
 ; SDAG-X86-NEXT:    retl
 ;
+; SDAG-X86-CMOV-LABEL: select_cmov_i16:
+; SDAG-X86-CMOV:       ## %bb.0:
+; SDAG-X86-CMOV-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; SDAG-X86-CMOV-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-CMOV-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-CMOV-NEXT:    cmovnel %eax, %ecx
+; SDAG-X86-CMOV-NEXT:    movzwl (%ecx), %eax
+; SDAG-X86-CMOV-NEXT:    retl
+;
 ; FAST-X86-LABEL: select_cmov_i16:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
@@ -132,6 +176,14 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
 ; FAST-X86-NEXT:    movzwl %ax, %eax
 ; FAST-X86-NEXT:    retl
 ;
+; FAST-X86-CMOV-LABEL: select_cmov_i16:
+; FAST-X86-CMOV:       ## %bb.0:
+; FAST-X86-CMOV-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
+; FAST-X86-CMOV-NEXT:    cmovew {{[0-9]+}}(%esp), %ax
+; FAST-X86-CMOV-NEXT:    movzwl %ax, %eax
+; FAST-X86-CMOV-NEXT:    retl
+;
 ; GISEL-X86-LABEL: select_cmov_i16:
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -145,6 +197,16 @@ define zeroext i16 @select_cmov_i16(i1 zeroext %cond, i16 zeroext %a, i16 zeroex
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
 ; GISEL-X86-NEXT:    retl
+;
+; GISEL-X86-CMOV-LABEL: select_cmov_i16:
+; GISEL-X86-CMOV:       ## %bb.0:
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-CMOV-NEXT:    andl $1, %ecx
+; GISEL-X86-CMOV-NEXT:    cmovnew %dx, %ax
+; GISEL-X86-CMOV-NEXT:    ## kill: def $ax killed $ax killed $eax
+; GISEL-X86-CMOV-NEXT:    retl
   %1 = select i1 %cond, i16 %a, i16 %b
   ret i16 %1
 }
@@ -187,6 +249,15 @@ define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
 ; SDAG-X86-NEXT:    movzwl %ax, %eax
 ; SDAG-X86-NEXT:    retl
 ;
+; SDAG-X86-CMOV-LABEL: select_cmp_cmov_i16:
+; SDAG-X86-CMOV:       ## %bb.0:
+; SDAG-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-CMOV-NEXT:    cmpw %ax, %cx
+; SDAG-X86-CMOV-NEXT:    cmovbl %ecx, %eax
+; SDAG-X86-CMOV-NEXT:    movzwl %ax, %eax
+; SDAG-X86-CMOV-NEXT:    retl
+;
 ; FAST-X86-LABEL: select_cmp_cmov_i16:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
@@ -199,6 +270,15 @@ define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
 ; FAST-X86-NEXT:    movzwl %ax, %eax
 ; FAST-X86-NEXT:    retl
 ;
+; FAST-X86-CMOV-LABEL: select_cmp_cmov_i16:
+; FAST-X86-CMOV:       ## %bb.0:
+; FAST-X86-CMOV-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; FAST-X86-CMOV-NEXT:    cmpw %ax, %cx
+; FAST-X86-CMOV-NEXT:    cmovbw %cx, %ax
+; FAST-X86-CMOV-NEXT:    movzwl %ax, %eax
+; FAST-X86-CMOV-NEXT:    retl
+;
 ; GISEL-X86-LABEL: select_cmp_cmov_i16:
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
@@ -213,6 +293,18 @@ define zeroext i16 @select_cmp_cmov_i16(i16 zeroext %a, i16 zeroext %b) {
 ; GISEL-X86-NEXT:  LBB2_2:
 ; GISEL-X86-NEXT:    ## kill: def $ax killed $ax killed $eax
 ; GISEL-X86-NEXT:    retl
+;
+; GISEL-X86-CMOV-LABEL: select_cmp_cmov_i16:
+; GISEL-X86-CMOV:       ## %bb.0:
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-CMOV-NEXT:    xorl %edx, %edx
+; GISEL-X86-CMOV-NEXT:    cmpw %cx, %ax
+; GISEL-X86-CMOV-NEXT:    setb %dl
+; GISEL-X86-CMOV-NEXT:    andl $1, %edx
+; GISEL-X86-CMOV-NEXT:    cmovew %cx, %ax
+; GISEL-X86-CMOV-NEXT:    ## kill: def $ax killed $ax killed $eax
+; GISEL-X86-CMOV-NEXT:    retl
   %1 = icmp ult i16 %a, %b
   %2 = select i1 %1, i16 %a, i16 %b
   ret i16 %2
@@ -253,6 +345,15 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
 ; SDAG-X86-NEXT:    movl (%eax), %eax
 ; SDAG-X86-NEXT:    retl
 ;
+; SDAG-X86-CMOV-LABEL: select_cmov_i32:
+; SDAG-X86-CMOV:       ## %bb.0:
+; SDAG-X86-CMOV-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; SDAG-X86-CMOV-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-CMOV-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-CMOV-NEXT:    cmovnel %eax, %ecx
+; SDAG-X86-CMOV-NEXT:    movl (%ecx), %eax
+; SDAG-X86-CMOV-NEXT:    retl
+;
 ; FAST-X86-LABEL: select_cmov_i32:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    testb $1, {{[0-9]+}}(%esp)
@@ -264,6 +365,13 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    retl
 ;
+; FAST-X86-CMOV-LABEL: select_cmov_i32:
+; FAST-X86-CMOV:       ## %bb.0:
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    testb $1, {{[0-9]+}}(%esp)
+; FAST-X86-CMOV-NEXT:    cmovel {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    retl
+;
 ; GISEL-X86-LABEL: select_cmov_i32:
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
@@ -275,6 +383,14 @@ define i32 @select_cmov_i32(i1 zeroext %cond, i32 %a, i32 %b) {
 ; GISEL-X86-NEXT:  LBB3_1:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; GISEL-X86-NEXT:    retl
+;
+; GISEL-X86-CMOV-LABEL: select_cmov_i32:
+; GISEL-X86-CMOV:       ## %bb.0:
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-CMOV-NEXT:    andl $1, %ecx
+; GISEL-X86-CMOV-NEXT:    cmovnel {{[0-9]+}}(%esp), %eax
+; GISEL-X86-CMOV-NEXT:    retl
   %1 = select i1 %cond, i32 %a, i32 %b
   ret i32 %1
 }
@@ -315,6 +431,14 @@ define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
 ; SDAG-X86-NEXT:  LBB4_2:
 ; SDAG-X86-NEXT:    retl
 ;
+; SDAG-X86-CMOV-LABEL: select_cmp_cmov_i32:
+; SDAG-X86-CMOV:       ## %bb.0:
+; SDAG-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-CMOV-NEXT:    cmpl %eax, %ecx
+; SDAG-X86-CMOV-NEXT:    cmovbl %ecx, %eax
+; SDAG-X86-CMOV-NEXT:    retl
+;
 ; FAST-X86-LABEL: select_cmp_cmov_i32:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
@@ -326,6 +450,14 @@ define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
 ; FAST-X86-NEXT:  LBB4_2:
 ; FAST-X86-NEXT:    retl
 ;
+; FAST-X86-CMOV-LABEL: select_cmp_cmov_i32:
+; FAST-X86-CMOV:       ## %bb.0:
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; FAST-X86-CMOV-NEXT:    cmpl %eax, %ecx
+; FAST-X86-CMOV-NEXT:    cmovbl %ecx, %eax
+; FAST-X86-CMOV-NEXT:    retl
+;
 ; GISEL-X86-LABEL: select_cmp_cmov_i32:
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
@@ -339,6 +471,17 @@ define i32 @select_cmp_cmov_i32(i32 %a, i32 %b) {
 ; GISEL-X86-NEXT:    movl %ecx, %eax
 ; GISEL-X86-NEXT:  LBB4_2:
 ; GISEL-X86-NEXT:    retl
+;
+; GISEL-X86-CMOV-LABEL: select_cmp_cmov_i32:
+; GISEL-X86-CMOV:       ## %bb.0:
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-CMOV-NEXT:    xorl %edx, %edx
+; GISEL-X86-CMOV-NEXT:    cmpl %ecx, %eax
+; GISEL-X86-CMOV-NEXT:    setb %dl
+; GISEL-X86-CMOV-NEXT:    andl $1, %edx
+; GISEL-X86-CMOV-NEXT:    cmovel %ecx, %eax
+; GISEL-X86-CMOV-NEXT:    retl
   %1 = icmp ult i32 %a, %b
   %2 = select i1 %1, i32 %a, i32 %b
   ret i32 %2
@@ -380,6 +523,16 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
 ; SDAG-X86-NEXT:    movl 4(%ecx), %edx
 ; SDAG-X86-NEXT:    retl
 ;
+; SDAG-X86-CMOV-LABEL: select_cmov_i64:
+; SDAG-X86-CMOV:       ## %bb.0:
+; SDAG-X86-CMOV-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; SDAG-X86-CMOV-NEXT:    leal {{[0-9]+}}(%esp), %eax
+; SDAG-X86-CMOV-NEXT:    leal {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-CMOV-NEXT:    cmovnel %eax, %ecx
+; SDAG-X86-CMOV-NEXT:    movl (%ecx), %eax
+; SDAG-X86-CMOV-NEXT:    movl 4(%ecx), %edx
+; SDAG-X86-CMOV-NEXT:    retl
+;
 ; FAST-X86-LABEL: select_cmov_i64:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
@@ -393,6 +546,15 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
 ; FAST-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
 ; FAST-X86-NEXT:    retl
 ;
+; FAST-X86-CMOV-LABEL: select_cmov_i64:
+; FAST-X86-CMOV:       ## %bb.0:
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    cmpb $0, {{[0-9]+}}(%esp)
+; FAST-X86-CMOV-NEXT:    cmovel {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    cmovel {{[0-9]+}}(%esp), %edx
+; FAST-X86-CMOV-NEXT:    retl
+;
 ; GISEL-X86-LABEL: select_cmov_i64:
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
@@ -412,6 +574,16 @@ define i64 @select_cmov_i64(i1 zeroext %cond, i64 %a, i64 %b) {
 ; GISEL-X86-NEXT:  LBB5_5:
 ; GISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
 ; GISEL-X86-NEXT:    retl
+;
+; GISEL-X86-CMOV-LABEL: select_cmov_i64:
+; GISEL-X86-CMOV:       ## %bb.0:
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-CMOV-NEXT:    andl $1, %ecx
+; GISEL-X86-CMOV-NEXT:    cmovnel {{[0-9]+}}(%esp), %eax
+; GISEL-X86-CMOV-NEXT:    cmovnel {{[0-9]+}}(%esp), %edx
+; GISEL-X86-CMOV-NEXT:    retl
   %1 = select i1 %cond, i64 %a, i64 %b
   ret i64 %1
 }
@@ -461,6 +633,23 @@ define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
 ; SDAG-X86-NEXT:    popl %edi
 ; SDAG-X86-NEXT:    retl
 ;
+; SDAG-X86-CMOV-LABEL: select_cmp_cmov_i64:
+; SDAG-X86-CMOV:       ## %bb.0:
+; SDAG-X86-CMOV-NEXT:    pushl %edi
+; SDAG-X86-CMOV-NEXT:    pushl %esi
+; SDAG-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; SDAG-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; SDAG-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; SDAG-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; SDAG-X86-CMOV-NEXT:    cmpl %eax, %ecx
+; SDAG-X86-CMOV-NEXT:    movl %esi, %edi
+; SDAG-X86-CMOV-NEXT:    sbbl %edx, %edi
+; SDAG-X86-CMOV-NEXT:    cmovbl %ecx, %eax
+; SDAG-X86-CMOV-NEXT:    cmovbl %esi, %edx
+; SDAG-X86-CMOV-NEXT:    popl %esi
+; SDAG-X86-CMOV-NEXT:    popl %edi
+; SDAG-X86-CMOV-NEXT:    retl
+;
 ; FAST-X86-LABEL: select_cmp_cmov_i64:
 ; FAST-X86:       ## %bb.0:
 ; FAST-X86-NEXT:    pushl %edi
@@ -481,6 +670,23 @@ define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
 ; FAST-X86-NEXT:    popl %edi
 ; FAST-X86-NEXT:    retl
 ;
+; FAST-X86-CMOV-LABEL: select_cmp_cmov_i64:
+; FAST-X86-CMOV:       ## %bb.0:
+; FAST-X86-CMOV-NEXT:    pushl %edi
+; FAST-X86-CMOV-NEXT:    pushl %esi
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; FAST-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; FAST-X86-CMOV-NEXT:    cmpl %eax, %esi
+; FAST-X86-CMOV-NEXT:    movl %ecx, %edi
+; FAST-X86-CMOV-NEXT:    sbbl %edx, %edi
+; FAST-X86-CMOV-NEXT:    cmovbl %esi, %eax
+; FAST-X86-CMOV-NEXT:    cmovbl %ecx, %edx
+; FAST-X86-CMOV-NEXT:    popl %esi
+; FAST-X86-CMOV-NEXT:    popl %edi
+; FAST-X86-CMOV-NEXT:    retl
+;
 ; GISEL-X86-LABEL: select_cmp_cmov_i64:
 ; GISEL-X86:       ## %bb.0:
 ; GISEL-X86-NEXT:    pushl %ebp
@@ -518,6 +724,36 @@ define i64 @select_cmp_cmov_i64(i64 %a, i64 %b) nounwind {
 ; GISEL-X86-NEXT:    popl %ebx
 ; GISEL-X86-NEXT:    popl %ebp
 ; GISEL-X86-NEXT:    retl
+;
+; GISEL-X86-CMOV-LABEL: select_cmp_cmov_i64:
+; GISEL-X86-CMOV:       ## %bb.0:
+; GISEL-X86-CMOV-NEXT:    pushl %ebp
+; GISEL-X86-CMOV-NEXT:    pushl %ebx
+; GISEL-X86-CMOV-NEXT:    pushl %edi
+; GISEL-X86-CMOV-NEXT:    pushl %esi
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %ebp
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; GISEL-X86-CMOV-NEXT:    movl {{[0-9]+}}(%esp), %edi
+; GISEL-X86-CMOV-NEXT:    xorl %ebx, %ebx
+; GISEL-X86-CMOV-NEXT:    xorl %ecx, %ecx
+; GISEL-X86-CMOV-NEXT:    cmpl %edi, %edx
+; GISEL-X86-CMOV-NEXT:    setb %bl
+; GISEL-X86-CMOV-NEXT:    sete %cl
+; GISEL-X86-CMOV-NEXT:    xorl %eax, %eax
+; GISEL-X86-CMOV-NEXT:    cmpl %esi, %ebp
+; GISEL-X86-CMOV-NEXT:    setb %al
+; GISEL-X86-CMOV-NEXT:    testl %ecx, %ecx
+; GISEL-X86-CMOV-NEXT:    cmovnew %ax, %bx
+; GISEL-X86-CMOV-NEXT:    andl $1, %ebx
+; GISEL-X86-CMOV-NEXT:    cmovel %esi, %ebp
+; GISEL-X86-CMOV-NEXT:    cmovel %edi, %edx
+; GISEL-X86-CMOV-NEXT:    movl %ebp, %eax
+; GISEL-X86-CMOV-NEXT:    popl %esi
+; GISEL-X86-CMOV-NEXT:    popl %edi
+; GISEL-X86-CMOV-NEXT:    popl %ebx
+; GISEL-X86-CMOV-NEXT:    popl %ebp
+; GISEL-X86-CMOV-NEXT:    retl
   %1 = icmp ult i64 %a, %b
   %2 = select i1 %1, i64 %a, i64 %b
   ret i64 %2



More information about the llvm-commits mailing list