Skip to content

Conversation

mahesh-attarde
Copy link
Contributor

Original PR broke in rebase #160247. Continuing here
This patch adds support for G_[U|S][MIN|MAX] opcodes into X86 Target.

This PR addressed review comments

  1. About Widening to next power of 2 [X86][GlobalIsel] Add support for G_UMIN/G_UMAX/G_SMIN/G_SMAX #160247 (comment)
  2. clamping scalar [X86][GlobalIsel] Add support for G_UMIN/G_UMAX/G_SMIN/G_SMAX #160247 (comment)

@llvmbot
Copy link
Member

llvmbot commented Oct 3, 2025

@llvm/pr-subscribers-backend-x86

Author: Mahesh-Attarde (mahesh-attarde)

Changes

Original PR broke in rebase #160247. Continuing here
This patch adds support for G_[U|S][MIN|MAX] opcodes into X86 Target.

This PR addressed review comments

  1. About Widening to next power of 2 [X86][GlobalIsel] Add support for G_UMIN/G_UMAX/G_SMIN/G_SMAX #160247 (comment)
  2. clamping scalar [X86][GlobalIsel] Add support for G_UMIN/G_UMAX/G_SMIN/G_SMAX #160247 (comment)

Patch is 45.55 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/161783.diff

5 Files Affected:

  • (modified) llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp (+4)
  • (modified) llvm/test/CodeGen/X86/isel-smax.ll (+162-82)
  • (modified) llvm/test/CodeGen/X86/isel-smin.ll (+162-82)
  • (modified) llvm/test/CodeGen/X86/isel-umax.ll (+162-82)
  • (modified) llvm/test/CodeGen/X86/isel-umin.ll (+162-82)
diff --git a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
index ee9760f881ae9..0d4c3a2127ddd 100644
--- a/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
+++ b/llvm/lib/Target/X86/GISel/X86LegalizerInfo.cpp
@@ -149,6 +149,10 @@ X86LegalizerInfo::X86LegalizerInfo(const X86Subtarget &STI,
         });
   }
 
+  getActionDefinitionsBuilder({G_UMIN, G_UMAX, G_SMIN, G_SMAX})
+      .widenScalarToNextPow2(0, /*Min=*/32)
+      .lower();
+
   // integer addition/subtraction
   getActionDefinitionsBuilder({G_ADD, G_SUB})
       .legalFor({s8, s16, s32})
diff --git a/llvm/test/CodeGen/X86/isel-smax.ll b/llvm/test/CodeGen/X86/isel-smax.ll
index 9c9a48e3a1b3e..1ce0a8006bb74 100644
--- a/llvm/test/CodeGen/X86/isel-smax.ll
+++ b/llvm/test/CodeGen/X86/isel-smax.ll
@@ -1,19 +1,19 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=X64
-; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel | FileCheck %s --check-prefixes=FASTISEL-X64
-; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes=X64
-; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=X86
-; RUN: llc < %s -mtriple=i686-linux-gnu -fast-isel | FileCheck %s --check-prefixes=FASTISEL-X86
-; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes=X86
+; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=X64,DAG-X64
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel | FileCheck %s --check-prefixes=X64,FASTISEL-X64
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X64
+; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=X86,DAG-X86
+; RUN: llc < %s -mtriple=i686-linux-gnu -fast-isel | FileCheck %s --check-prefixes=X86,FASTISEL-X86
+; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X86
 
 define i8 @smax_i8(i8 %a, i8 %b) nounwind readnone {
-; X64-LABEL: smax_i8:
-; X64:       # %bb.0:
-; X64-NEXT:    movl %esi, %eax
-; X64-NEXT:    cmpb %al, %dil
-; X64-NEXT:    cmovgl %edi, %eax
-; X64-NEXT:    # kill: def $al killed $al killed $eax
-; X64-NEXT:    retq
+; DAG-X64-LABEL: smax_i8:
+; DAG-X64:       # %bb.0:
+; DAG-X64-NEXT:    movl %esi, %eax
+; DAG-X64-NEXT:    cmpb %al, %dil
+; DAG-X64-NEXT:    cmovgl %edi, %eax
+; DAG-X64-NEXT:    # kill: def $al killed $al killed $eax
+; DAG-X64-NEXT:    retq
 ;
 ; FASTISEL-X64-LABEL: smax_i8:
 ; FASTISEL-X64:       # %bb.0:
@@ -24,6 +24,17 @@ define i8 @smax_i8(i8 %a, i8 %b) nounwind readnone {
 ; FASTISEL-X64-NEXT:    # kill: def $al killed $al killed $eax
 ; FASTISEL-X64-NEXT:    retq
 ;
+; GISEL-X64-LABEL: smax_i8:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    movl %esi, %eax
+; GISEL-X64-NEXT:    xorl %ecx, %ecx
+; GISEL-X64-NEXT:    cmpb %al, %dil
+; GISEL-X64-NEXT:    setg %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovnew %di, %ax
+; GISEL-X64-NEXT:    # kill: def $al killed $al killed $eax
+; GISEL-X64-NEXT:    retq
+;
 ; X86-LABEL: smax_i8:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
@@ -35,16 +46,20 @@ define i8 @smax_i8(i8 %a, i8 %b) nounwind readnone {
 ; X86-NEXT:  .LBB0_2:
 ; X86-NEXT:    retl
 ;
-; FASTISEL-X86-LABEL: smax_i8:
-; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; FASTISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
-; FASTISEL-X86-NEXT:    cmpb %cl, %al
-; FASTISEL-X86-NEXT:    jg .LBB0_2
-; FASTISEL-X86-NEXT:  # %bb.1:
-; FASTISEL-X86-NEXT:    movl %ecx, %eax
-; FASTISEL-X86-NEXT:  .LBB0_2:
-; FASTISEL-X86-NEXT:    retl
+; GISEL-X86-LABEL: smax_i8:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    xorl %edx, %edx
+; GISEL-X86-NEXT:    cmpb %al, %cl
+; GISEL-X86-NEXT:    setg %dl
+; GISEL-X86-NEXT:    andl $1, %edx
+; GISEL-X86-NEXT:    je .LBB0_2
+; GISEL-X86-NEXT:  # %bb.1:
+; GISEL-X86-NEXT:    movl %ecx, %eax
+; GISEL-X86-NEXT:  .LBB0_2:
+; GISEL-X86-NEXT:    # kill: def $al killed $al killed $eax
+; GISEL-X86-NEXT:    retl
     %ret = call i8 @llvm.smax.i8(i8 %a, i8 %b)
     ret i8 %ret
 }
@@ -57,25 +72,28 @@ define i16 @smax_i16(i16 %a, i16 %b) nounwind readnone {
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
 ;
-; FASTISEL-X64-LABEL: smax_i16:
-; FASTISEL-X64:       # %bb.0:
-; FASTISEL-X64-NEXT:    movl %esi, %eax
-; FASTISEL-X64-NEXT:    cmpw %ax, %di
-; FASTISEL-X64-NEXT:    cmovgl %edi, %eax
-; FASTISEL-X64-NEXT:    # kill: def $ax killed $ax killed $eax
-; FASTISEL-X64-NEXT:    retq
+; GISEL-X64-LABEL: smax_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:    setg %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovew %si, %ax
+; GISEL-X64-NEXT:    # kill: def $ax killed $ax killed $eax
+; GISEL-X64-NEXT:    retq
 ;
-; X86-LABEL: smax_i16:
-; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    cmpw %cx, %ax
-; X86-NEXT:    jg .LBB1_2
-; X86-NEXT:  # %bb.1:
-; X86-NEXT:    movl %ecx, %eax
-; X86-NEXT:  .LBB1_2:
-; X86-NEXT:    # kill: def $ax killed $ax killed $eax
-; X86-NEXT:    retl
+; DAG-X86-LABEL: smax_i16:
+; DAG-X86:       # %bb.0:
+; DAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; DAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; DAG-X86-NEXT:    cmpw %cx, %ax
+; DAG-X86-NEXT:    jg .LBB1_2
+; DAG-X86-NEXT:  # %bb.1:
+; DAG-X86-NEXT:    movl %ecx, %eax
+; DAG-X86-NEXT:  .LBB1_2:
+; DAG-X86-NEXT:    # kill: def $ax killed $ax killed $eax
+; DAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: smax_i16:
 ; FASTISEL-X86:       # %bb.0:
@@ -88,6 +106,21 @@ define i16 @smax_i16(i16 %a, i16 %b) nounwind readnone {
 ; FASTISEL-X86-NEXT:  .LBB1_2:
 ; FASTISEL-X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; FASTISEL-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: smax_i16:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    xorl %edx, %edx
+; GISEL-X86-NEXT:    cmpw %ax, %cx
+; GISEL-X86-NEXT:    setg %dl
+; GISEL-X86-NEXT:    andl $1, %edx
+; GISEL-X86-NEXT:    je .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
     %ret = call i16 @llvm.smax.i16(i16 %a, i16 %b)
     ret i16 %ret
 }
@@ -99,12 +132,15 @@ define i32 @smax_i32(i32 %a, i32 %b) nounwind readnone {
 ; X64-NEXT:    cmovgl %edi, %eax
 ; X64-NEXT:    retq
 ;
-; FASTISEL-X64-LABEL: smax_i32:
-; FASTISEL-X64:       # %bb.0:
-; FASTISEL-X64-NEXT:    movl %esi, %eax
-; FASTISEL-X64-NEXT:    cmpl %esi, %edi
-; FASTISEL-X64-NEXT:    cmovgl %edi, %eax
-; FASTISEL-X64-NEXT:    retq
+; GISEL-X64-LABEL: smax_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:    setg %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovel %esi, %eax
+; GISEL-X64-NEXT:    retq
 ;
 ; X86-LABEL: smax_i32:
 ; X86:       # %bb.0:
@@ -117,16 +153,19 @@ define i32 @smax_i32(i32 %a, i32 %b) nounwind readnone {
 ; X86-NEXT:  .LBB2_2:
 ; X86-NEXT:    retl
 ;
-; FASTISEL-X86-LABEL: smax_i32:
-; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; FASTISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; FASTISEL-X86-NEXT:    cmpl %ecx, %eax
-; FASTISEL-X86-NEXT:    jg .LBB2_2
-; FASTISEL-X86-NEXT:  # %bb.1:
-; FASTISEL-X86-NEXT:    movl %ecx, %eax
-; FASTISEL-X86-NEXT:  .LBB2_2:
-; FASTISEL-X86-NEXT:    retl
+; GISEL-X86-LABEL: smax_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:    setg %dl
+; GISEL-X86-NEXT:    andl $1, %edx
+; GISEL-X86-NEXT:    je .LBB2_2
+; GISEL-X86-NEXT:  # %bb.1:
+; GISEL-X86-NEXT:    movl %ecx, %eax
+; GISEL-X86-NEXT:  .LBB2_2:
+; GISEL-X86-NEXT:    retl
     %ret = call i32 @llvm.smax.i32(i32 %a, i32 %b)
     ret i32 %ret
 }
@@ -138,32 +177,35 @@ define i64 @smax_i64(i64 %a, i64 %b) nounwind readnone {
 ; X64-NEXT:    cmovgq %rdi, %rax
 ; X64-NEXT:    retq
 ;
-; FASTISEL-X64-LABEL: smax_i64:
-; FASTISEL-X64:       # %bb.0:
-; FASTISEL-X64-NEXT:    movq %rsi, %rax
-; FASTISEL-X64-NEXT:    cmpq %rsi, %rdi
-; FASTISEL-X64-NEXT:    cmovgq %rdi, %rax
-; FASTISEL-X64-NEXT:    retq
+; GISEL-X64-LABEL: smax_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:    setg %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmoveq %rsi, %rax
+; GISEL-X64-NEXT:    retq
 ;
-; X86-LABEL: smax_i64:
-; X86:       # %bb.0:
-; X86-NEXT:    pushl %edi
-; X86-NEXT:    pushl %esi
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
-; X86-NEXT:    cmpl %eax, %ecx
-; X86-NEXT:    movl %esi, %edi
-; X86-NEXT:    sbbl %edx, %edi
-; X86-NEXT:    jl .LBB3_2
-; X86-NEXT:  # %bb.1:
-; X86-NEXT:    movl %ecx, %eax
-; X86-NEXT:    movl %esi, %edx
-; X86-NEXT:  .LBB3_2:
-; X86-NEXT:    popl %esi
-; X86-NEXT:    popl %edi
-; X86-NEXT:    retl
+; DAG-X86-LABEL: smax_i64:
+; DAG-X86:       # %bb.0:
+; DAG-X86-NEXT:    pushl %edi
+; DAG-X86-NEXT:    pushl %esi
+; DAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; DAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %edx
+; DAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; DAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %esi
+; DAG-X86-NEXT:    cmpl %eax, %ecx
+; DAG-X86-NEXT:    movl %esi, %edi
+; DAG-X86-NEXT:    sbbl %edx, %edi
+; DAG-X86-NEXT:    jl .LBB3_2
+; DAG-X86-NEXT:  # %bb.1:
+; DAG-X86-NEXT:    movl %ecx, %eax
+; DAG-X86-NEXT:    movl %esi, %edx
+; DAG-X86-NEXT:  .LBB3_2:
+; DAG-X86-NEXT:    popl %esi
+; DAG-X86-NEXT:    popl %edi
+; DAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: smax_i64:
 ; FASTISEL-X86:       # %bb.0:
@@ -184,6 +226,44 @@ define i64 @smax_i64(i64 %a, i64 %b) nounwind readnone {
 ; FASTISEL-X86-NEXT:    popl %esi
 ; FASTISEL-X86-NEXT:    popl %edi
 ; FASTISEL-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: smax_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:    cmpl %eax, %esi
+; GISEL-X86-NEXT:    seta %bl
+; GISEL-X86-NEXT:    xorl %ecx, %ecx
+; GISEL-X86-NEXT:    cmpl %edx, %ebp
+; GISEL-X86-NEXT:    setg %bh
+; GISEL-X86-NEXT:    sete %cl
+; GISEL-X86-NEXT:    testl %ecx, %ecx
+; GISEL-X86-NEXT:    je .LBB3_2
+; GISEL-X86-NEXT:  # %bb.1:
+; GISEL-X86-NEXT:    movb %bl, %bh
+; GISEL-X86-NEXT:  .LBB3_2:
+; GISEL-X86-NEXT:    movzbl %bh, %edi
+; GISEL-X86-NEXT:    andl $1, %edi
+; GISEL-X86-NEXT:    je .LBB3_4
+; GISEL-X86-NEXT:  # %bb.3:
+; GISEL-X86-NEXT:    movl %esi, %eax
+; GISEL-X86-NEXT:  .LBB3_4:
+; GISEL-X86-NEXT:    testl %edi, %edi
+; GISEL-X86-NEXT:    je .LBB3_6
+; GISEL-X86-NEXT:  # %bb.5:
+; GISEL-X86-NEXT:    movl %ebp, %edx
+; GISEL-X86-NEXT:  .LBB3_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
     %ret = call i64 @llvm.smax.i64(i64 %a, i64 %b)
     ret i64 %ret
 }
diff --git a/llvm/test/CodeGen/X86/isel-smin.ll b/llvm/test/CodeGen/X86/isel-smin.ll
index 7349a7c6a06f3..bbed3c356cb3b 100644
--- a/llvm/test/CodeGen/X86/isel-smin.ll
+++ b/llvm/test/CodeGen/X86/isel-smin.ll
@@ -1,19 +1,19 @@
 ; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
-; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=X64
-; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel | FileCheck %s --check-prefixes=FASTISEL-X64
-; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes=X64
-; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=X86
-; RUN: llc < %s -mtriple=i686-linux-gnu -fast-isel | FileCheck %s --check-prefixes=FASTISEL-X86
-; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=2 | FileCheck %s --check-prefixes=X86
+; RUN: llc < %s -mtriple=x86_64-linux-gnu | FileCheck %s --check-prefixes=X64,DAG-X64
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -fast-isel | FileCheck %s --check-prefixes=X64,FASTISEL-X64
+; RUN: llc < %s -mtriple=x86_64-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X64
+; RUN: llc < %s -mtriple=i686-linux-gnu | FileCheck %s --check-prefixes=X86,DAG-X86
+; RUN: llc < %s -mtriple=i686-linux-gnu -fast-isel | FileCheck %s --check-prefixes=X86,FASTISEL-X86
+; RUN: llc < %s -mtriple=i686-linux-gnu -global-isel -global-isel-abort=1 | FileCheck %s --check-prefixes=GISEL-X86
 
 define i8 @smin_i8(i8 %a, i8 %b) nounwind readnone {
-; X64-LABEL: smin_i8:
-; X64:       # %bb.0:
-; X64-NEXT:    movl %esi, %eax
-; X64-NEXT:    cmpb %al, %dil
-; X64-NEXT:    cmovll %edi, %eax
-; X64-NEXT:    # kill: def $al killed $al killed $eax
-; X64-NEXT:    retq
+; DAG-X64-LABEL: smin_i8:
+; DAG-X64:       # %bb.0:
+; DAG-X64-NEXT:    movl %esi, %eax
+; DAG-X64-NEXT:    cmpb %al, %dil
+; DAG-X64-NEXT:    cmovll %edi, %eax
+; DAG-X64-NEXT:    # kill: def $al killed $al killed $eax
+; DAG-X64-NEXT:    retq
 ;
 ; FASTISEL-X64-LABEL: smin_i8:
 ; FASTISEL-X64:       # %bb.0:
@@ -24,6 +24,17 @@ define i8 @smin_i8(i8 %a, i8 %b) nounwind readnone {
 ; FASTISEL-X64-NEXT:    # kill: def $al killed $al killed $eax
 ; FASTISEL-X64-NEXT:    retq
 ;
+; GISEL-X64-LABEL: smin_i8:
+; GISEL-X64:       # %bb.0:
+; GISEL-X64-NEXT:    movl %esi, %eax
+; GISEL-X64-NEXT:    xorl %ecx, %ecx
+; GISEL-X64-NEXT:    cmpb %al, %dil
+; GISEL-X64-NEXT:    setl %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovnew %di, %ax
+; GISEL-X64-NEXT:    # kill: def $al killed $al killed $eax
+; GISEL-X64-NEXT:    retq
+;
 ; X86-LABEL: smin_i8:
 ; X86:       # %bb.0:
 ; X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
@@ -35,16 +46,20 @@ define i8 @smin_i8(i8 %a, i8 %b) nounwind readnone {
 ; X86-NEXT:  .LBB0_2:
 ; X86-NEXT:    retl
 ;
-; FASTISEL-X86-LABEL: smin_i8:
-; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
-; FASTISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
-; FASTISEL-X86-NEXT:    cmpb %cl, %al
-; FASTISEL-X86-NEXT:    jl .LBB0_2
-; FASTISEL-X86-NEXT:  # %bb.1:
-; FASTISEL-X86-NEXT:    movl %ecx, %eax
-; FASTISEL-X86-NEXT:  .LBB0_2:
-; FASTISEL-X86-NEXT:    retl
+; GISEL-X86-LABEL: smin_i8:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movzbl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    xorl %edx, %edx
+; GISEL-X86-NEXT:    cmpb %al, %cl
+; GISEL-X86-NEXT:    setl %dl
+; GISEL-X86-NEXT:    andl $1, %edx
+; GISEL-X86-NEXT:    je .LBB0_2
+; GISEL-X86-NEXT:  # %bb.1:
+; GISEL-X86-NEXT:    movl %ecx, %eax
+; GISEL-X86-NEXT:  .LBB0_2:
+; GISEL-X86-NEXT:    # kill: def $al killed $al killed $eax
+; GISEL-X86-NEXT:    retl
     %ret = call i8 @llvm.smin.i8(i8 %a, i8 %b)
     ret i8 %ret
 }
@@ -57,25 +72,28 @@ define i16 @smin_i16(i16 %a, i16 %b) nounwind readnone {
 ; X64-NEXT:    # kill: def $ax killed $ax killed $eax
 ; X64-NEXT:    retq
 ;
-; FASTISEL-X64-LABEL: smin_i16:
-; FASTISEL-X64:       # %bb.0:
-; FASTISEL-X64-NEXT:    movl %esi, %eax
-; FASTISEL-X64-NEXT:    cmpw %ax, %di
-; FASTISEL-X64-NEXT:    cmovll %edi, %eax
-; FASTISEL-X64-NEXT:    # kill: def $ax killed $ax killed $eax
-; FASTISEL-X64-NEXT:    retq
+; GISEL-X64-LABEL: smin_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:    setl %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovew %si, %ax
+; GISEL-X64-NEXT:    # kill: def $ax killed $ax killed $eax
+; GISEL-X64-NEXT:    retq
 ;
-; X86-LABEL: smin_i16:
-; X86:       # %bb.0:
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT:    cmpw %cx, %ax
-; X86-NEXT:    jl .LBB1_2
-; X86-NEXT:  # %bb.1:
-; X86-NEXT:    movl %ecx, %eax
-; X86-NEXT:  .LBB1_2:
-; X86-NEXT:    # kill: def $ax killed $ax killed $eax
-; X86-NEXT:    retl
+; DAG-X86-LABEL: smin_i16:
+; DAG-X86:       # %bb.0:
+; DAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
+; DAG-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
+; DAG-X86-NEXT:    cmpw %cx, %ax
+; DAG-X86-NEXT:    jl .LBB1_2
+; DAG-X86-NEXT:  # %bb.1:
+; DAG-X86-NEXT:    movl %ecx, %eax
+; DAG-X86-NEXT:  .LBB1_2:
+; DAG-X86-NEXT:    # kill: def $ax killed $ax killed $eax
+; DAG-X86-NEXT:    retl
 ;
 ; FASTISEL-X86-LABEL: smin_i16:
 ; FASTISEL-X86:       # %bb.0:
@@ -88,6 +106,21 @@ define i16 @smin_i16(i16 %a, i16 %b) nounwind readnone {
 ; FASTISEL-X86-NEXT:  .LBB1_2:
 ; FASTISEL-X86-NEXT:    # kill: def $ax killed $ax killed $eax
 ; FASTISEL-X86-NEXT:    retl
+;
+; GISEL-X86-LABEL: smin_i16:
+; GISEL-X86:       # %bb.0:
+; GISEL-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %ecx
+; GISEL-X86-NEXT:    movzwl {{[0-9]+}}(%esp), %eax
+; GISEL-X86-NEXT:    xorl %edx, %edx
+; GISEL-X86-NEXT:    cmpw %ax, %cx
+; GISEL-X86-NEXT:    setl %dl
+; GISEL-X86-NEXT:    andl $1, %edx
+; GISEL-X86-NEXT:    je .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
     %ret = call i16 @llvm.smin.i16(i16 %a, i16 %b)
     ret i16 %ret
 }
@@ -99,12 +132,15 @@ define i32 @smin_i32(i32 %a, i32 %b) nounwind readnone {
 ; X64-NEXT:    cmovll %edi, %eax
 ; X64-NEXT:    retq
 ;
-; FASTISEL-X64-LABEL: smin_i32:
-; FASTISEL-X64:       # %bb.0:
-; FASTISEL-X64-NEXT:    movl %esi, %eax
-; FASTISEL-X64-NEXT:    cmpl %esi, %edi
-; FASTISEL-X64-NEXT:    cmovll %edi, %eax
-; FASTISEL-X64-NEXT:    retq
+; GISEL-X64-LABEL: smin_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:    setl %cl
+; GISEL-X64-NEXT:    andl $1, %ecx
+; GISEL-X64-NEXT:    cmovel %esi, %eax
+; GISEL-X64-NEXT:    retq
 ;
 ; X86-LABEL: smin_i32:
 ; X86:       # %bb.0:
@@ -117,16 +153,19 @@ define i32 @smin_i32(i32 %a, i32 %b) nounwind readnone {
 ; X86-NEXT:  .LBB2_2:
 ; X86-NEXT:    retl
 ;
-; FASTISEL-X86-LABEL: smin_i32:
-; FASTISEL-X86:       # %bb.0:
-; FASTISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %ecx
-; FASTISEL-X86-NEXT:    movl {{[0-9]+}}(%esp), %eax
-; FASTISEL-X86-NEXT:    cmpl %ecx, %eax
-; FASTISEL-X86-NEXT:    jl .LBB2_2
-; FASTISEL-X86-NEXT:  # %bb.1:
-; FASTISEL-X86-NEXT:    movl %ecx, %eax
-; FASTISEL-X86-NEXT:  .LBB2_2:
-; FASTISEL-X86-NEXT:    retl
+; GISEL-X86-LABEL: smin_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:    setl %dl
+; GISEL-X86-NEXT:    andl $1, %edx
+; GISEL-X86-NEXT:    je .LBB2_2
+; GISEL-X86-NEXT:  # %bb.1:
+; GISEL-X86-NEXT:    movl %ecx, %eax
+; GISEL-X86-NEXT:  .LBB2_2:
+; GISEL-X86-NEXT:    retl
     %ret = call i32 @llvm.smin.i32(i32 %a, i32 %b)
     ret i32 %ret
 }
@@ -138,32 +177,35 @@ define i64 @smin_i64(i64 %a, i64 %b) nounwind readnone {
 ; X64-NEXT:    cmovlq %rdi, %rax
 ; X64-NEXT:    retq
 ;
-; FASTISEL-X64-LABEL: smin_i64:
-; FASTISEL-X64:       # %bb.0:
-; FASTISEL-X64-NEXT:    movq %rsi, %rax
-; FASTISEL-X64-NEXT:    cmpq %rsi, %rdi
-; FASTISEL-X64-NEXT:    cmovlq %rdi, %rax
-; FASTISEL-X64-NEXT:    retq
+; GISEL-X64-LABEL: smi...
[truncated]

@RKSimon RKSimon requested review from e-kud and RKSimon October 3, 2025 06:38
Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - cheers

@RKSimon RKSimon enabled auto-merge (squash) October 3, 2025 09:10
@RKSimon RKSimon merged commit 72679c8 into llvm:main Oct 3, 2025
9 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Oct 3, 2025

LLVM Buildbot has detected a new failure on builder mlir-nvidia-gcc7 running on mlir-nvidia while building llvm at step 7 "test-build-check-mlir-build-only-check-mlir".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/116/builds/19211

Here is the relevant piece of the build log for the reference
Step 7 (test-build-check-mlir-build-only-check-mlir) failure: test (failure)
******************** TEST 'MLIR :: Integration/GPU/CUDA/async.mlir' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
/vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.src/mlir/test/Integration/GPU/CUDA/async.mlir  | /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -gpu-kernel-outlining  | /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -pass-pipeline='builtin.module(gpu.module(strip-debuginfo,convert-gpu-to-nvvm),nvvm-attach-target)'  | /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -gpu-async-region -gpu-to-llvm -reconcile-unrealized-casts -gpu-module-to-binary="format=fatbin"  | /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -async-to-async-runtime -async-runtime-ref-counting  | /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -convert-async-to-llvm -convert-func-to-llvm -convert-arith-to-llvm -convert-cf-to-llvm -reconcile-unrealized-casts  | /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-runner    --shared-libs=/vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/lib/libmlir_cuda_runtime.so    --shared-libs=/vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/lib/libmlir_async_runtime.so    --shared-libs=/vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/lib/libmlir_runner_utils.so    --entry-point-result=void -O0  | /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/FileCheck /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.src/mlir/test/Integration/GPU/CUDA/async.mlir
# executed command: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.src/mlir/test/Integration/GPU/CUDA/async.mlir
# executed command: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -gpu-kernel-outlining
# executed command: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt '-pass-pipeline=builtin.module(gpu.module(strip-debuginfo,convert-gpu-to-nvvm),nvvm-attach-target)'
# executed command: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -gpu-async-region -gpu-to-llvm -reconcile-unrealized-casts -gpu-module-to-binary=format=fatbin
# executed command: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -async-to-async-runtime -async-runtime-ref-counting
# executed command: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-opt -convert-async-to-llvm -convert-func-to-llvm -convert-arith-to-llvm -convert-cf-to-llvm -reconcile-unrealized-casts
# executed command: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/mlir-runner --shared-libs=/vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/lib/libmlir_cuda_runtime.so --shared-libs=/vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/lib/libmlir_async_runtime.so --shared-libs=/vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/lib/libmlir_runner_utils.so --entry-point-result=void -O0
# .---command stderr------------
# | 'cuStreamWaitEvent(stream, event, 0)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuEventDestroy(event)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuStreamWaitEvent(stream, event, 0)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuEventDestroy(event)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuStreamWaitEvent(stream, event, 0)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuStreamWaitEvent(stream, event, 0)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuEventDestroy(event)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuEventDestroy(event)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuEventSynchronize(event)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# | 'cuEventDestroy(event)' failed with 'CUDA_ERROR_CONTEXT_IS_DESTROYED'
# `-----------------------------
# executed command: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.obj/bin/FileCheck /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.src/mlir/test/Integration/GPU/CUDA/async.mlir
# .---command stderr------------
# | /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.src/mlir/test/Integration/GPU/CUDA/async.mlir:68:12: error: CHECK: expected string not found in input
# |  // CHECK: [84, 84]
# |            ^
# | <stdin>:1:1: note: scanning from here
# | Unranked Memref base@ = 0x5d3fdec55920 rank = 1 offset = 0 sizes = [2] strides = [1] data = 
# | ^
# | <stdin>:2:1: note: possible intended match here
# | [42, 42]
# | ^
# | 
# | Input file: <stdin>
# | Check file: /vol/worker/mlir-nvidia/mlir-nvidia-gcc7/llvm.src/mlir/test/Integration/GPU/CUDA/async.mlir
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |             1: Unranked Memref base@ = 0x5d3fdec55920 rank = 1 offset = 0 sizes = [2] strides = [1] data =  
# | check:68'0     X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ error: no match found
# |             2: [42, 42] 
# | check:68'0     ~~~~~~~~~
# | check:68'1     ?         possible intended match
...

@mahesh-attarde mahesh-attarde deleted the gisel_min_max_1 branch October 3, 2025 10:01
MixedMatched pushed a commit to MixedMatched/llvm-project that referenced this pull request Oct 3, 2025
…161783)

Original PR broke in rebase
llvm#160247. Continuing here
This patch adds support for G_[U|S][MIN|MAX] opcodes into X86 Target.

This PR addressed review comments
1. About Widening to next power of 2
llvm#160247 (comment)
2. clamping scalar
llvm#160247 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants