From 96e1c907c36078658f147c6c11f12c051a5b137c Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Thu, 20 Nov 2025 13:18:38 +0000 Subject: [PATCH 1/2] [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 120c38ab8404c..e19f14b863ee3 100644 --- a/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/LegalizerHelper.cpp @@ -8657,7 +8657,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 845da6fb95378a24c2e7196c684e0dae4db3b21a Mon Sep 17 00:00:00 2001 From: Nathan Corbyn Date: Fri, 21 Nov 2025 13:17:55 +0000 Subject: [PATCH 2/2] 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>) +...