diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td index a1d39d910bc8e0..5d4b5a2479f6a4 100644 --- a/llvm/include/llvm/Target/GlobalISel/Combine.td +++ b/llvm/include/llvm/Target/GlobalISel/Combine.td @@ -1309,7 +1309,7 @@ def select_to_minmax: GICombineRule< def select_to_iminmax: GICombineRule< (defs root:$root, build_fn_matchinfo:$info), - (match (G_ICMP $tst, $tst1, $x, $y), + (match (G_ICMP $tst, $tst1, $a, $b), (G_SELECT $root, $tst, $x, $y), [{ return Helper.matchSelectIMinMax(${root}, ${info}); }]), (apply [{ Helper.applyBuildFnMO(${root}, ${info}); }])>; diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index a87a26d72b4525..22eb4a3e0d7cb1 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -6772,13 +6772,20 @@ bool CombinerHelper::matchSelectIMinMax(const MachineOperand &MO, if (CmpInst::isEquality(Pred)) return false; - [[maybe_unused]] Register CmpLHS = Cmp->getLHSReg(); - [[maybe_unused]] Register CmpRHS = Cmp->getRHSReg(); + Register CmpLHS = Cmp->getLHSReg(); + Register CmpRHS = Cmp->getRHSReg(); + + // We can swap CmpLHS and CmpRHS for higher hitrate. + if (True == CmpRHS && False == CmpLHS) { + std::swap(CmpLHS, CmpRHS); + Pred = CmpInst::getSwappedPredicate(Pred); + } // (icmp X, Y) ? X : Y -> integer minmax. // see matchSelectPattern in ValueTracking. // Legality between G_SELECT and integer minmax can differ. - assert(True == CmpLHS && False == CmpRHS && "unexpected MIR pattern"); + if (True != CmpLHS || False != CmpRHS) + return false; switch (Pred) { case ICmpInst::ICMP_UGT: diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir index 8d9ad8d7cacaf2..353c1550d69746 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir @@ -911,8 +911,7 @@ body: | ; CHECK-NEXT: %f1:_(s32) = G_TRUNC [[COPY1]](s64) ; CHECK-NEXT: %t:_(<4 x s32>) = G_BUILD_VECTOR %t1(s32), %t1(s32), %t1(s32), %t1(s32) ; CHECK-NEXT: %f:_(<4 x s32>) = G_BUILD_VECTOR %f1(s32), %f1(s32), %f1(s32), %f1(s32) - ; CHECK-NEXT: %c:_(<4 x s32>) = G_ICMP intpred(sle), %f(<4 x s32>), %t - ; CHECK-NEXT: %sel:_(<4 x s32>) = exact G_SELECT %c(<4 x s32>), %t, %f + ; CHECK-NEXT: %sel:_(<4 x s32>) = G_SMAX %t, %f ; CHECK-NEXT: $q0 = COPY %sel(<4 x s32>) %0:_(s64) = COPY $x0 %1:_(s64) = COPY $x1