[llvm] [GlobalISel] Don't permit G_*MIN/G_*MAX of pointer vectors (PR #168872)

Nathan Corbyn via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 16 07:35:32 PST 2025


https://github.com/cofibrant updated https://github.com/llvm/llvm-project/pull/168872

>From 70cfebf14e77445bbcff706b57b9cbca519a8f87 Mon Sep 17 00:00:00 2001
From: Nathan Corbyn <n_corbyn at apple.com>
Date: Thu, 20 Nov 2025 13:18:38 +0000
Subject: [PATCH 1/5] [AArch64][GlobalISel] Don't crash when legalising 
 G_*MIN/G_*MAX of pointer vector

---
 .../CodeGen/GlobalISel/LegalizerHelper.cpp    |   2 +-
 .../GlobalISel/legalize-min-max-crash.mir     | 174 ++++++++++++++++++
 2 files changed, 175 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir

diff --git a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
index 802738ba19a70..6fce22e091cf9 100644
--- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp
@@ -8663,7 +8663,7 @@ LegalizerHelper::LegalizeResult LegalizerHelper::lowerMinMax(MachineInstr &MI) {
   auto [Dst, Src0, Src1] = MI.getFirst3Regs();
 
   const CmpInst::Predicate Pred = minMaxToCompare(MI.getOpcode());
-  LLT CmpType = MRI.getType(Dst).changeElementSize(1);
+  LLT CmpType = MRI.getType(Dst).changeElementType(LLT::scalar(1));
 
   auto Cmp = MIRBuilder.buildICmp(Pred, CmpType, Src0, Src1);
   MIRBuilder.buildSelect(Dst, Cmp, Src0, Src1);
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir
new file mode 100644
index 0000000000000..23d8f0bab4487
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir
@@ -0,0 +1,174 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+# RUN: llc -o - -mtriple=aarch64 -run-pass=legalizer -verify-machineinstrs %s | FileCheck %s
+---
+name:            g_umax
+legalized:       false
+body:             |
+  bb.0:
+    liveins: $q0, $q1
+
+    ; CHECK-LABEL: name: g_umax
+    ; CHECK: liveins: $q0, $q1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x p0>) = G_BUILD_VECTOR [[C]](p0), [[C]](p0)
+    ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
+    ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ugt), [[BITCAST]](<2 x p0>), [[BUILD_VECTOR]]
+    ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ugt), [[BITCAST1]](<2 x p0>), [[BUILD_VECTOR]]
+    ; CHECK-NEXT: [[BITCAST2:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
+    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST2]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT1:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST3]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT2:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT3:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C1]](s64), [[C1]](s64)
+    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR1]]
+    ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]]
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT]], [[ICMP]]
+    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT1]], [[ICMP1]]
+    ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT2]], [[XOR]]
+    ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT3]], [[XOR1]]
+    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
+    ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
+    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR]](<2 x s64>)
+    ; CHECK-NEXT: [[INTTOPTR1:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR1]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR]](<2 x p0>)
+    ; CHECK-NEXT: [[BITCAST5:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR1]](<2 x p0>)
+    ; CHECK-NEXT: $q0 = COPY [[BITCAST4]](<2 x s64>)
+    ; CHECK-NEXT: $q1 = COPY [[BITCAST5]](<2 x s64>)
+    ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+    %1:_(<2 x s64>) = COPY $q0
+    %2:_(<2 x s64>) = COPY $q1
+    %0:_(<4 x p0>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
+    %4:_(p0) = G_CONSTANT i64 0
+    %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
+    %6:_(<4 x p0>) = G_UMAX %0, %3
+    %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)
+    $q0 = COPY %7(<2 x s64>)
+    $q1 = COPY %8(<2 x s64>)
+    RET_ReallyLR implicit $q0, implicit $q1
+...
+---
+name:            g_umin
+legalized:       false
+body:             |
+  bb.0:
+    liveins: $q0, $q1
+
+    ; CHECK-LABEL: name: g_umin
+    ; CHECK: liveins: $q0, $q1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x p0>) = G_BUILD_VECTOR [[C]](p0), [[C]](p0)
+    ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
+    ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ult), [[BITCAST]](<2 x p0>), [[BUILD_VECTOR]]
+    ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ult), [[BITCAST1]](<2 x p0>), [[BUILD_VECTOR]]
+    ; CHECK-NEXT: [[BITCAST2:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
+    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST2]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT1:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST3]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT2:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT3:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C1]](s64), [[C1]](s64)
+    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR1]]
+    ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]]
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT]], [[ICMP]]
+    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT1]], [[ICMP1]]
+    ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT2]], [[XOR]]
+    ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT3]], [[XOR1]]
+    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
+    ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
+    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR]](<2 x s64>)
+    ; CHECK-NEXT: [[INTTOPTR1:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR1]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR]](<2 x p0>)
+    ; CHECK-NEXT: [[BITCAST5:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR1]](<2 x p0>)
+    ; CHECK-NEXT: $q0 = COPY [[BITCAST4]](<2 x s64>)
+    ; CHECK-NEXT: $q1 = COPY [[BITCAST5]](<2 x s64>)
+    ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+    %1:_(<2 x s64>) = COPY $q0
+    %2:_(<2 x s64>) = COPY $q1
+    %0:_(<4 x p0>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
+    %4:_(p0) = G_CONSTANT i64 0
+    %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
+    %6:_(<4 x p0>) = G_UMIN %0, %3
+    %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)
+    $q0 = COPY %7(<2 x s64>)
+    $q1 = COPY %8(<2 x s64>)
+    RET_ReallyLR implicit $q0, implicit $q1
+...
+---
+name:            g_smax
+legalized:       false
+body:             |
+  bb.0:
+    liveins: $q0, $q1
+
+    ; CHECK-LABEL: name: g_smax
+    ; CHECK: liveins: $q0, $q1
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
+    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x p0>) = G_BUILD_VECTOR [[C]](p0), [[C]](p0)
+    ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
+    ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(sgt), [[BITCAST]](<2 x p0>), [[BUILD_VECTOR]]
+    ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(sgt), [[BITCAST1]](<2 x p0>), [[BUILD_VECTOR]]
+    ; CHECK-NEXT: [[BITCAST2:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
+    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST2]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT1:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST3]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT2:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
+    ; CHECK-NEXT: [[PTRTOINT3:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
+    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+    ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C1]](s64), [[C1]](s64)
+    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR1]]
+    ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]]
+    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT]], [[ICMP]]
+    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT1]], [[ICMP1]]
+    ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT2]], [[XOR]]
+    ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT3]], [[XOR1]]
+    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
+    ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
+    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR]](<2 x s64>)
+    ; CHECK-NEXT: [[INTTOPTR1:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR1]](<2 x s64>)
+    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR]](<2 x p0>)
+    ; CHECK-NEXT: [[BITCAST5:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR1]](<2 x p0>)
+    ; CHECK-NEXT: $q0 = COPY [[BITCAST4]](<2 x s64>)
+    ; CHECK-NEXT: $q1 = COPY [[BITCAST5]](<2 x s64>)
+    ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
+    %1:_(<2 x s64>) = COPY $q0
+    %2:_(<2 x s64>) = COPY $q1
+    %0:_(<4 x p0>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
+    %4:_(p0) = G_CONSTANT i64 0
+    %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
+    %6:_(<4 x p0>) = G_SMAX %0, %3
+    %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)
+    $q0 = COPY %7(<2 x s64>)
+    $q1 = COPY %8(<2 x s64>)
+    RET_ReallyLR implicit $q0, implicit $q1
+...
+---
+name:            g_smin
+legalized:       false
+body:             |
+  bb.0:
+    liveins: $q0, $q1
+
+    ; CHECK-LABEL: name: g_smin
+    ; CHECK: liveins: $q0, $q1
+    %1:_(<2 x s64>) = COPY $q0
+    %2:_(<2 x s64>) = COPY $q1
+    %0:_(<4 x p0>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
+    %4:_(p0) = G_CONSTANT i64 0
+    %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
+    %6:_(<4 x p0>) = G_SMIN %0, %3
+    %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)

>From 05e9c26c0b437abfc5d485d691cd5912b5ca5ed5 Mon Sep 17 00:00:00 2001
From: Nathan Corbyn <n_corbyn at apple.com>
Date: Fri, 21 Nov 2025 13:17:55 +0000
Subject: [PATCH 2/5] Update MIR test

---
 .../test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir
index 23d8f0bab4487..31b016836e135 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir
@@ -1,5 +1,5 @@
 # NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
-# RUN: llc -o - -mtriple=aarch64 -run-pass=legalizer -verify-machineinstrs %s | FileCheck %s
+# RUN: llc -o - -mtriple=aarch64 -run-pass=legalizer %s | FileCheck %s
 ---
 name:            g_umax
 legalized:       false
@@ -172,3 +172,4 @@ body:             |
     %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
     %6:_(<4 x p0>) = G_SMIN %0, %3
     %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)
+...

>From f9b4113e0ae98eecc237179fa350c1b216951d71 Mon Sep 17 00:00:00 2001
From: Nathan Corbyn <n_corbyn at apple.com>
Date: Tue, 16 Dec 2025 13:08:39 +0000
Subject: [PATCH 3/5] Reject `G_*MAX`/`G_*MIN` for pointer vectors in
 MachineVerifier

---
 .../lib/CodeGen/GlobalISel/CombinerHelper.cpp |   4 +-
 llvm/lib/CodeGen/MachineVerifier.cpp          |  10 +
 .../GlobalISel/legalize-min-max-crash.mir     | 175 ------------------
 .../CodeGen/AArch64/GlobalISel/pr168872.ll    |  48 +++++
 llvm/test/MachineVerifier/test_g_minmax.mir   |  35 ++++
 5 files changed, 95 insertions(+), 177 deletions(-)
 delete mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir
 create mode 100644 llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll
 create mode 100644 llvm/test/MachineVerifier/test_g_minmax.mir

diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index f0fbe0135353f..c58969144dc2b 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -7556,7 +7556,7 @@ bool CombinerHelper::matchSelectIMinMax(const MachineOperand &MO,
   Register False = Select->getFalseReg();
   LLT DstTy = MRI.getType(DstReg);
 
-  if (DstTy.isPointer())
+  if (DstTy.isPointerOrPointerVector())
     return false;
 
   // We want to fold the icmp and replace the select.
@@ -8511,4 +8511,4 @@ bool CombinerHelper::matchSuboCarryOut(const MachineInstr &MI,
   }
 
   return false;
-}
\ No newline at end of file
+}
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index 9be741d96e456..5ce7606b051a5 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -2276,6 +2276,16 @@ void MachineVerifier::verifyPreISelGenericInstruction(const MachineInstr *MI) {
       report("addr operand must be a pointer", &AddrOp, 1);
     break;
   }
+  case TargetOpcode::G_SMIN:
+  case TargetOpcode::G_SMAX:
+  case TargetOpcode::G_UMIN:
+  case TargetOpcode::G_UMAX: {
+    const LLT DstTy = MRI->getType(MI->getOperand(0).getReg());
+    if (DstTy.isPointerOrPointerVector())
+      report("Generic smin/smax/umin/umax does not support pointer operands",
+             MI);
+    break;
+  }
   default:
     break;
   }
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir
deleted file mode 100644
index 31b016836e135..0000000000000
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-min-max-crash.mir
+++ /dev/null
@@ -1,175 +0,0 @@
-# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
-# RUN: llc -o - -mtriple=aarch64 -run-pass=legalizer %s | FileCheck %s
----
-name:            g_umax
-legalized:       false
-body:             |
-  bb.0:
-    liveins: $q0, $q1
-
-    ; CHECK-LABEL: name: g_umax
-    ; CHECK: liveins: $q0, $q1
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
-    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
-    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x p0>) = G_BUILD_VECTOR [[C]](p0), [[C]](p0)
-    ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
-    ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ugt), [[BITCAST]](<2 x p0>), [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ugt), [[BITCAST1]](<2 x p0>), [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[BITCAST2:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
-    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST2]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT1:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST3]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT2:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT3:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
-    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C1]](s64), [[C1]](s64)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR1]]
-    ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT]], [[ICMP]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT1]], [[ICMP1]]
-    ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT2]], [[XOR]]
-    ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT3]], [[XOR1]]
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
-    ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
-    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR]](<2 x s64>)
-    ; CHECK-NEXT: [[INTTOPTR1:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR1]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR]](<2 x p0>)
-    ; CHECK-NEXT: [[BITCAST5:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR1]](<2 x p0>)
-    ; CHECK-NEXT: $q0 = COPY [[BITCAST4]](<2 x s64>)
-    ; CHECK-NEXT: $q1 = COPY [[BITCAST5]](<2 x s64>)
-    ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
-    %1:_(<2 x s64>) = COPY $q0
-    %2:_(<2 x s64>) = COPY $q1
-    %0:_(<4 x p0>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
-    %4:_(p0) = G_CONSTANT i64 0
-    %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
-    %6:_(<4 x p0>) = G_UMAX %0, %3
-    %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)
-    $q0 = COPY %7(<2 x s64>)
-    $q1 = COPY %8(<2 x s64>)
-    RET_ReallyLR implicit $q0, implicit $q1
-...
----
-name:            g_umin
-legalized:       false
-body:             |
-  bb.0:
-    liveins: $q0, $q1
-
-    ; CHECK-LABEL: name: g_umin
-    ; CHECK: liveins: $q0, $q1
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
-    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
-    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x p0>) = G_BUILD_VECTOR [[C]](p0), [[C]](p0)
-    ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
-    ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ult), [[BITCAST]](<2 x p0>), [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ult), [[BITCAST1]](<2 x p0>), [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[BITCAST2:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
-    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST2]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT1:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST3]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT2:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT3:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
-    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C1]](s64), [[C1]](s64)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR1]]
-    ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT]], [[ICMP]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT1]], [[ICMP1]]
-    ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT2]], [[XOR]]
-    ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT3]], [[XOR1]]
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
-    ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
-    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR]](<2 x s64>)
-    ; CHECK-NEXT: [[INTTOPTR1:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR1]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR]](<2 x p0>)
-    ; CHECK-NEXT: [[BITCAST5:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR1]](<2 x p0>)
-    ; CHECK-NEXT: $q0 = COPY [[BITCAST4]](<2 x s64>)
-    ; CHECK-NEXT: $q1 = COPY [[BITCAST5]](<2 x s64>)
-    ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
-    %1:_(<2 x s64>) = COPY $q0
-    %2:_(<2 x s64>) = COPY $q1
-    %0:_(<4 x p0>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
-    %4:_(p0) = G_CONSTANT i64 0
-    %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
-    %6:_(<4 x p0>) = G_UMIN %0, %3
-    %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)
-    $q0 = COPY %7(<2 x s64>)
-    $q1 = COPY %8(<2 x s64>)
-    RET_ReallyLR implicit $q0, implicit $q1
-...
----
-name:            g_smax
-legalized:       false
-body:             |
-  bb.0:
-    liveins: $q0, $q1
-
-    ; CHECK-LABEL: name: g_smax
-    ; CHECK: liveins: $q0, $q1
-    ; CHECK-NEXT: {{  $}}
-    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
-    ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
-    ; CHECK-NEXT: [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
-    ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<2 x p0>) = G_BUILD_VECTOR [[C]](p0), [[C]](p0)
-    ; CHECK-NEXT: [[BITCAST:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST1:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
-    ; CHECK-NEXT: [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(sgt), [[BITCAST]](<2 x p0>), [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(sgt), [[BITCAST1]](<2 x p0>), [[BUILD_VECTOR]]
-    ; CHECK-NEXT: [[BITCAST2:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST3:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
-    ; CHECK-NEXT: [[PTRTOINT:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST2]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT1:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST3]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT2:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
-    ; CHECK-NEXT: [[PTRTOINT3:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
-    ; CHECK-NEXT: [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
-    ; CHECK-NEXT: [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C1]](s64), [[C1]](s64)
-    ; CHECK-NEXT: [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR1]]
-    ; CHECK-NEXT: [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]]
-    ; CHECK-NEXT: [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT]], [[ICMP]]
-    ; CHECK-NEXT: [[AND1:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT1]], [[ICMP1]]
-    ; CHECK-NEXT: [[AND2:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT2]], [[XOR]]
-    ; CHECK-NEXT: [[AND3:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT3]], [[XOR1]]
-    ; CHECK-NEXT: [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
-    ; CHECK-NEXT: [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
-    ; CHECK-NEXT: [[INTTOPTR:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR]](<2 x s64>)
-    ; CHECK-NEXT: [[INTTOPTR1:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR1]](<2 x s64>)
-    ; CHECK-NEXT: [[BITCAST4:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR]](<2 x p0>)
-    ; CHECK-NEXT: [[BITCAST5:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR1]](<2 x p0>)
-    ; CHECK-NEXT: $q0 = COPY [[BITCAST4]](<2 x s64>)
-    ; CHECK-NEXT: $q1 = COPY [[BITCAST5]](<2 x s64>)
-    ; CHECK-NEXT: RET_ReallyLR implicit $q0, implicit $q1
-    %1:_(<2 x s64>) = COPY $q0
-    %2:_(<2 x s64>) = COPY $q1
-    %0:_(<4 x p0>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
-    %4:_(p0) = G_CONSTANT i64 0
-    %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
-    %6:_(<4 x p0>) = G_SMAX %0, %3
-    %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)
-    $q0 = COPY %7(<2 x s64>)
-    $q1 = COPY %8(<2 x s64>)
-    RET_ReallyLR implicit $q0, implicit $q1
-...
----
-name:            g_smin
-legalized:       false
-body:             |
-  bb.0:
-    liveins: $q0, $q1
-
-    ; CHECK-LABEL: name: g_smin
-    ; CHECK: liveins: $q0, $q1
-    %1:_(<2 x s64>) = COPY $q0
-    %2:_(<2 x s64>) = COPY $q1
-    %0:_(<4 x p0>) = G_CONCAT_VECTORS %1(<2 x s64>), %2(<2 x s64>)
-    %4:_(p0) = G_CONSTANT i64 0
-    %3:_(<4 x p0>) = G_BUILD_VECTOR %4(p0), %4(p0), %4(p0), %4(p0)
-    %6:_(<4 x p0>) = G_SMIN %0, %3
-    %7:_(<2 x s64>), %8:_(<2 x s64>) = G_UNMERGE_VALUES %6(<4 x p0>)
-...
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll b/llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll
new file mode 100644
index 0000000000000..6a7ce844df0a5
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll
@@ -0,0 +1,48 @@
+; NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py UTC_ARGS: --version 6
+; RUN: llc -global-isel -stop-after=legalizer -o - %s | FileCheck %s
+target triple = "aarch64"
+
+; Check we don't crash here or try to generate an ill-formed `G_UMAX` of
+; pointer vectors.
+
+define <4 x ptr> @pr168872(<4 x ptr> %0) {
+  ; CHECK-LABEL: name: pr168872
+  ; CHECK: bb.1.entry:
+  ; CHECK-NEXT:   liveins: $q0, $q1
+  ; CHECK-NEXT: {{  $}}
+  ; CHECK-NEXT:   [[COPY:%[0-9]+]]:_(<2 x s64>) = COPY $q0
+  ; CHECK-NEXT:   [[COPY1:%[0-9]+]]:_(<2 x s64>) = COPY $q1
+  ; CHECK-NEXT:   [[C:%[0-9]+]]:_(p0) = G_CONSTANT i64 0
+  ; CHECK-NEXT:   [[BUILD_VECTOR:%[0-9]+]]:_(<2 x p0>) = G_BUILD_VECTOR [[C]](p0), [[C]](p0)
+  ; CHECK-NEXT:   [[BITCAST:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
+  ; CHECK-NEXT:   [[BITCAST1:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
+  ; CHECK-NEXT:   [[ICMP:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ugt), [[BITCAST]](<2 x p0>), [[BUILD_VECTOR]]
+  ; CHECK-NEXT:   [[ICMP1:%[0-9]+]]:_(<2 x s64>) = G_ICMP intpred(ugt), [[BITCAST1]](<2 x p0>), [[BUILD_VECTOR]]
+  ; CHECK-NEXT:   [[BITCAST2:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY]](<2 x s64>)
+  ; CHECK-NEXT:   [[BITCAST3:%[0-9]+]]:_(<2 x p0>) = G_BITCAST [[COPY1]](<2 x s64>)
+  ; CHECK-NEXT:   [[PTRTOINT:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST2]](<2 x p0>)
+  ; CHECK-NEXT:   [[PTRTOINT1:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BITCAST3]](<2 x p0>)
+  ; CHECK-NEXT:   [[PTRTOINT2:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
+  ; CHECK-NEXT:   [[PTRTOINT3:%[0-9]+]]:_(<2 x s64>) = G_PTRTOINT [[BUILD_VECTOR]](<2 x p0>)
+  ; CHECK-NEXT:   [[C1:%[0-9]+]]:_(s64) = G_CONSTANT i64 -1
+  ; CHECK-NEXT:   [[BUILD_VECTOR1:%[0-9]+]]:_(<2 x s64>) = G_BUILD_VECTOR [[C1]](s64), [[C1]](s64)
+  ; CHECK-NEXT:   [[XOR:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP]], [[BUILD_VECTOR1]]
+  ; CHECK-NEXT:   [[XOR1:%[0-9]+]]:_(<2 x s64>) = G_XOR [[ICMP1]], [[BUILD_VECTOR1]]
+  ; CHECK-NEXT:   [[AND:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT]], [[ICMP]]
+  ; CHECK-NEXT:   [[AND1:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT1]], [[ICMP1]]
+  ; CHECK-NEXT:   [[AND2:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT2]], [[XOR]]
+  ; CHECK-NEXT:   [[AND3:%[0-9]+]]:_(<2 x s64>) = G_AND [[PTRTOINT3]], [[XOR1]]
+  ; CHECK-NEXT:   [[OR:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND]], [[AND2]]
+  ; CHECK-NEXT:   [[OR1:%[0-9]+]]:_(<2 x s64>) = G_OR [[AND1]], [[AND3]]
+  ; CHECK-NEXT:   [[INTTOPTR:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR]](<2 x s64>)
+  ; CHECK-NEXT:   [[INTTOPTR1:%[0-9]+]]:_(<2 x p0>) = G_INTTOPTR [[OR1]](<2 x s64>)
+  ; CHECK-NEXT:   [[BITCAST4:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR]](<2 x p0>)
+  ; CHECK-NEXT:   [[BITCAST5:%[0-9]+]]:_(<2 x s64>) = G_BITCAST [[INTTOPTR1]](<2 x p0>)
+  ; CHECK-NEXT:   $q0 = COPY [[BITCAST4]](<2 x s64>)
+  ; CHECK-NEXT:   $q1 = COPY [[BITCAST5]](<2 x s64>)
+  ; CHECK-NEXT:   RET_ReallyLR implicit $q0, implicit $q1
+entry:
+  %1 = icmp ugt <4 x ptr> %0, zeroinitializer
+  %2 = select <4 x i1> %1, <4 x ptr> %0, <4 x ptr> zeroinitializer
+  ret <4 x ptr> %2
+}
diff --git a/llvm/test/MachineVerifier/test_g_minmax.mir b/llvm/test/MachineVerifier/test_g_minmax.mir
new file mode 100644
index 0000000000000..187e6c7601770
--- /dev/null
+++ b/llvm/test/MachineVerifier/test_g_minmax.mir
@@ -0,0 +1,35 @@
+#RUN: not --crash llc -o - -mtriple=arm64 -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
+# REQUIRES: aarch64-registered-target
+
+---
+name:            test_minmax
+legalized:       true
+regBankSelected: false
+selected:        false
+tracksRegLiveness: true
+liveins:
+body:             |
+  bb.0:
+    ; Pointer operands
+    %0:_(p0) = G_CONSTANT i64 0
+    ; CHECK: Bad machine code: Generic smin/smax/umin/umax does not support pointer operands
+    %1:_(p0) = G_SMIN %0, %0
+    ; CHECK: Bad machine code: Generic smin/smax/umin/umax does not support pointer operands
+    %2:_(p0) = G_SMAX %0, %0
+    ; CHECK: Bad machine code: Generic smin/smax/umin/umax does not support pointer operands
+    %2:_(p0) = G_UMIN %0, %0
+    ; CHECK: Bad machine code: Generic smin/smax/umin/umax does not support pointer operands
+    %4:_(p0) = G_UMAX %0, %0
+
+    ; Pointer vector operands
+    %5:_(<4 x p0>) = G_IMPLICIT_DEF
+    ; CHECK: Bad machine code: Generic smin/smax/umin/umax does not support pointer operands
+    %6:_(<4 x p0>) = G_SMIN %5, %5
+    ; CHECK: Bad machine code: Generic smin/smax/umin/umax does not support pointer operands
+    %6:_(<4 x p0>) = G_SMIN %5, %5
+    ; CHECK: Bad machine code: Generic smin/smax/umin/umax does not support pointer operands
+    %6:_(<4 x p0>) = G_SMIN %5, %5
+    ; CHECK: Bad machine code: Generic smin/smax/umin/umax does not support pointer operands
+    %6:_(<4 x p0>) = G_SMIN %5, %5
+...
+

>From 5abd5af46f5e0d01e1f67a2304b40245b5fa7b4b Mon Sep 17 00:00:00 2001
From: Nathan Corbyn <n_corbyn at apple.com>
Date: Tue, 16 Dec 2025 15:33:00 +0000
Subject: [PATCH 4/5] Update tests

---
 llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll | 8 ++++----
 llvm/test/MachineVerifier/test_g_minmax.mir      | 7 +------
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll b/llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll
index 6a7ce844df0a5..4405c06ff0e23 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/pr168872.ll
@@ -5,7 +5,7 @@ target triple = "aarch64"
 ; Check we don't crash here or try to generate an ill-formed `G_UMAX` of
 ; pointer vectors.
 
-define <4 x ptr> @pr168872(<4 x ptr> %0) {
+define <4 x ptr> @pr168872(<4 x ptr> %ptrs) {
   ; CHECK-LABEL: name: pr168872
   ; CHECK: bb.1.entry:
   ; CHECK-NEXT:   liveins: $q0, $q1
@@ -42,7 +42,7 @@ define <4 x ptr> @pr168872(<4 x ptr> %0) {
   ; CHECK-NEXT:   $q1 = COPY [[BITCAST5]](<2 x s64>)
   ; CHECK-NEXT:   RET_ReallyLR implicit $q0, implicit $q1
 entry:
-  %1 = icmp ugt <4 x ptr> %0, zeroinitializer
-  %2 = select <4 x i1> %1, <4 x ptr> %0, <4 x ptr> zeroinitializer
-  ret <4 x ptr> %2
+  %cmp = icmp ugt <4 x ptr> %ptrs, zeroinitializer
+  %ptrs.select = select <4 x i1> %cmp, <4 x ptr> %ptrs, <4 x ptr> zeroinitializer
+  ret <4 x ptr> %ptrs.select
 }
diff --git a/llvm/test/MachineVerifier/test_g_minmax.mir b/llvm/test/MachineVerifier/test_g_minmax.mir
index 187e6c7601770..343065143ab73 100644
--- a/llvm/test/MachineVerifier/test_g_minmax.mir
+++ b/llvm/test/MachineVerifier/test_g_minmax.mir
@@ -1,13 +1,8 @@
-#RUN: not --crash llc -o - -mtriple=arm64 -global-isel -run-pass=none -verify-machineinstrs %s 2>&1 | FileCheck %s
+#RUN: not --crash llc -mtriple=arm64 -global-isel -run-pass=none -filetype=null %s 2>&1 | FileCheck %s
 # REQUIRES: aarch64-registered-target
 
 ---
 name:            test_minmax
-legalized:       true
-regBankSelected: false
-selected:        false
-tracksRegLiveness: true
-liveins:
 body:             |
   bb.0:
     ; Pointer operands

>From 96001caffb7cf8141e88d08de6a555636a255603 Mon Sep 17 00:00:00 2001
From: Nathan Corbyn <n_corbyn at apple.com>
Date: Tue, 16 Dec 2025 15:35:16 +0000
Subject: [PATCH 5/5] Update tests

---
 llvm/test/MachineVerifier/test_g_minmax.mir | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/llvm/test/MachineVerifier/test_g_minmax.mir b/llvm/test/MachineVerifier/test_g_minmax.mir
index 343065143ab73..303b0b5e96a01 100644
--- a/llvm/test/MachineVerifier/test_g_minmax.mir
+++ b/llvm/test/MachineVerifier/test_g_minmax.mir
@@ -2,8 +2,8 @@
 # REQUIRES: aarch64-registered-target
 
 ---
-name:            test_minmax
-body:             |
+name: test_minmax
+body: |
   bb.0:
     ; Pointer operands
     %0:_(p0) = G_CONSTANT i64 0



More information about the llvm-commits mailing list