diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h index f3b68623596c4..dcc1a4580b14a 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h @@ -910,9 +910,6 @@ class CombinerHelper { bool tryFoldSelectOfConstants(GSelect *Select, BuildFnTy &MatchInfo); - /// Try to fold select(cc, binop(), binop()) -> binop(select(), X) - bool tryFoldSelectOfBinOps(GSelect *Select, BuildFnTy &MatchInfo); - bool isOneOrOneSplat(Register Src, bool AllowUndefs); bool isZeroOrZeroSplat(Register Src, bool AllowUndefs); bool isConstantSplatVector(Register Src, int64_t SplatValue, diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h index 21d98d30356c9..6ab1d4550c51c 100644 --- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h +++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h @@ -558,109 +558,6 @@ class GVecReduce : public GenericMachineInstr { } }; -// Represents a binary operation, i.e, x = y op z. -class GBinOp : public GenericMachineInstr { -public: - Register getLHSReg() const { return getReg(1); } - Register getRHSReg() const { return getReg(2); } - - static bool classof(const MachineInstr *MI) { - switch (MI->getOpcode()) { - // Integer. - case TargetOpcode::G_ADD: - case TargetOpcode::G_SUB: - case TargetOpcode::G_MUL: - case TargetOpcode::G_SDIV: - case TargetOpcode::G_UDIV: - case TargetOpcode::G_SREM: - case TargetOpcode::G_UREM: - case TargetOpcode::G_SMIN: - case TargetOpcode::G_SMAX: - case TargetOpcode::G_UMIN: - case TargetOpcode::G_UMAX: - // Floating point. - case TargetOpcode::G_FMINNUM: - case TargetOpcode::G_FMAXNUM: - case TargetOpcode::G_FMINNUM_IEEE: - case TargetOpcode::G_FMAXNUM_IEEE: - case TargetOpcode::G_FMINIMUM: - case TargetOpcode::G_FMAXIMUM: - case TargetOpcode::G_FADD: - case TargetOpcode::G_FSUB: - case TargetOpcode::G_FMUL: - case TargetOpcode::G_FDIV: - case TargetOpcode::G_FPOW: - // Logical. - case TargetOpcode::G_AND: - case TargetOpcode::G_OR: - case TargetOpcode::G_XOR: - return true; - default: - return false; - } - }; -}; - -// Represents an integer binary operation. -class GIntBinOp : public GBinOp { -public: - static bool classof(const MachineInstr *MI) { - switch (MI->getOpcode()) { - case TargetOpcode::G_ADD: - case TargetOpcode::G_SUB: - case TargetOpcode::G_MUL: - case TargetOpcode::G_SDIV: - case TargetOpcode::G_UDIV: - case TargetOpcode::G_SREM: - case TargetOpcode::G_UREM: - case TargetOpcode::G_SMIN: - case TargetOpcode::G_SMAX: - case TargetOpcode::G_UMIN: - case TargetOpcode::G_UMAX: - return true; - default: - return false; - } - }; -}; - -// Represents a floating point binary operation. -class GFBinOp : public GBinOp { -public: - static bool classof(const MachineInstr *MI) { - switch (MI->getOpcode()) { - case TargetOpcode::G_FMINNUM: - case TargetOpcode::G_FMAXNUM: - case TargetOpcode::G_FMINNUM_IEEE: - case TargetOpcode::G_FMAXNUM_IEEE: - case TargetOpcode::G_FMINIMUM: - case TargetOpcode::G_FMAXIMUM: - case TargetOpcode::G_FADD: - case TargetOpcode::G_FSUB: - case TargetOpcode::G_FMUL: - case TargetOpcode::G_FDIV: - case TargetOpcode::G_FPOW: - return true; - default: - return false; - } - }; -}; - -// Represents a logical binary operation. -class GLogicalBinOp : public GBinOp { -public: - static bool classof(const MachineInstr *MI) { - switch (MI->getOpcode()) { - case TargetOpcode::G_AND: - case TargetOpcode::G_OR: - case TargetOpcode::G_XOR: - return true; - default: - return false; - } - }; -}; } // namespace llvm diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp index 5d8def4cca666..8b15bdb0aca30 100644 --- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp +++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp @@ -6390,7 +6390,8 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select, if (TrueValue.isZero() && FalseValue.isOne()) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Inner = B.buildNot(CondTy, Cond); + Register Inner = MRI.createGenericVirtualRegister(CondTy); + B.buildNot(Inner, Cond); B.buildZExtOrTrunc(Dest, Inner); }; return true; @@ -6400,7 +6401,8 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select, if (TrueValue.isZero() && FalseValue.isAllOnes()) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Inner = B.buildNot(CondTy, Cond); + Register Inner = MRI.createGenericVirtualRegister(CondTy); + B.buildNot(Inner, Cond); B.buildSExtOrTrunc(Dest, Inner); }; return true; @@ -6410,7 +6412,8 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select, if (TrueValue - 1 == FalseValue) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Inner = B.buildZExtOrTrunc(TrueTy, Cond); + Register Inner = MRI.createGenericVirtualRegister(TrueTy); + B.buildZExtOrTrunc(Inner, Cond); B.buildAdd(Dest, Inner, False); }; return true; @@ -6420,7 +6423,8 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select, if (TrueValue + 1 == FalseValue) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Inner = B.buildSExtOrTrunc(TrueTy, Cond); + Register Inner = MRI.createGenericVirtualRegister(TrueTy); + B.buildSExtOrTrunc(Inner, Cond); B.buildAdd(Dest, Inner, False); }; return true; @@ -6430,7 +6434,8 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select, if (TrueValue.isPowerOf2() && FalseValue.isZero()) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Inner = B.buildZExtOrTrunc(TrueTy, Cond); + Register Inner = MRI.createGenericVirtualRegister(TrueTy); + B.buildZExtOrTrunc(Inner, Cond); // The shift amount must be scalar. LLT ShiftTy = TrueTy.isVector() ? TrueTy.getElementType() : TrueTy; auto ShAmtC = B.buildConstant(ShiftTy, TrueValue.exactLogBase2()); @@ -6442,7 +6447,8 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select, if (TrueValue.isAllOnes()) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Inner = B.buildSExtOrTrunc(TrueTy, Cond); + Register Inner = MRI.createGenericVirtualRegister(TrueTy); + B.buildSExtOrTrunc(Inner, Cond); B.buildOr(Dest, Inner, False, Flags); }; return true; @@ -6452,8 +6458,10 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select, if (FalseValue.isAllOnes()) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Not = B.buildNot(CondTy, Cond); - auto Inner = B.buildSExtOrTrunc(TrueTy, Not); + Register Not = MRI.createGenericVirtualRegister(CondTy); + B.buildNot(Not, Cond); + Register Inner = MRI.createGenericVirtualRegister(TrueTy); + B.buildSExtOrTrunc(Inner, Not); B.buildOr(Dest, Inner, True, Flags); }; return true; @@ -6488,7 +6496,8 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select, if ((Cond == True) || isOneOrOneSplat(True, /* AllowUndefs */ true)) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Ext = B.buildZExtOrTrunc(TrueTy, Cond); + Register Ext = MRI.createGenericVirtualRegister(TrueTy); + B.buildZExtOrTrunc(Ext, Cond); B.buildOr(DstReg, Ext, False, Flags); }; return true; @@ -6499,7 +6508,8 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select, if ((Cond == False) || isZeroOrZeroSplat(False, /* AllowUndefs */ true)) { MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); - auto Ext = B.buildZExtOrTrunc(TrueTy, Cond); + Register Ext = MRI.createGenericVirtualRegister(TrueTy); + B.buildZExtOrTrunc(Ext, Cond); B.buildAnd(DstReg, Ext, True); }; return true; @@ -6510,9 +6520,11 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select, MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); // First the not. - auto Inner = B.buildNot(CondTy, Cond); + Register Inner = MRI.createGenericVirtualRegister(CondTy); + B.buildNot(Inner, Cond); // Then an ext to match the destination register. - auto Ext = B.buildZExtOrTrunc(TrueTy, Inner); + Register Ext = MRI.createGenericVirtualRegister(TrueTy); + B.buildZExtOrTrunc(Ext, Inner); B.buildOr(DstReg, Ext, True, Flags); }; return true; @@ -6523,9 +6535,11 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select, MatchInfo = [=](MachineIRBuilder &B) { B.setInstrAndDebugLoc(*Select); // First the not. - auto Inner = B.buildNot(CondTy, Cond); + Register Inner = MRI.createGenericVirtualRegister(CondTy); + B.buildNot(Inner, Cond); // Then an ext to match the destination register. - auto Ext = B.buildZExtOrTrunc(TrueTy, Inner); + Register Ext = MRI.createGenericVirtualRegister(TrueTy); + B.buildZExtOrTrunc(Ext, Inner); B.buildAnd(DstReg, Ext, False); }; return true; @@ -6534,54 +6548,6 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select, return false; } -bool CombinerHelper::tryFoldSelectOfBinOps(GSelect *Select, - BuildFnTy &MatchInfo) { - Register DstReg = Select->getReg(0); - Register Cond = Select->getCondReg(); - Register False = Select->getFalseReg(); - Register True = Select->getTrueReg(); - LLT DstTy = MRI.getType(DstReg); - - GBinOp *LHS = getOpcodeDef(True, MRI); - GBinOp *RHS = getOpcodeDef(False, MRI); - - // We need two binops of the same kind on the true/false registers. - if (!LHS || !RHS || LHS->getOpcode() != RHS->getOpcode()) - return false; - - // Note that there are no constraints on CondTy. - unsigned Flags = (LHS->getFlags() & RHS->getFlags()) | Select->getFlags(); - unsigned Opcode = LHS->getOpcode(); - - // Fold select(cond, binop(x, y), binop(z, y)) - // --> binop(select(cond, x, z), y) - if (LHS->getRHSReg() == RHS->getRHSReg()) { - MatchInfo = [=](MachineIRBuilder &B) { - B.setInstrAndDebugLoc(*Select); - auto Sel = B.buildSelect(DstTy, Cond, LHS->getLHSReg(), RHS->getLHSReg(), - Select->getFlags()); - B.buildInstr(Opcode, {DstReg}, {Sel, LHS->getRHSReg()}, Flags); - }; - return true; - } - - // Fold select(cond, binop(x, y), binop(x, z)) - // --> binop(x, select(cond, y, z)) - if (LHS->getLHSReg() == RHS->getLHSReg()) { - MatchInfo = [=](MachineIRBuilder &B) { - B.setInstrAndDebugLoc(*Select); - auto Sel = B.buildSelect(DstTy, Cond, LHS->getRHSReg(), RHS->getRHSReg(), - Select->getFlags()); - B.buildInstr(Opcode, {DstReg}, {LHS->getLHSReg(), Sel}, Flags); - }; - return true; - } - - // FIXME: use isCommutable(). - - return false; -} - bool CombinerHelper::matchSelect(MachineInstr &MI, BuildFnTy &MatchInfo) { GSelect *Select = cast(&MI); @@ -6591,8 +6557,5 @@ bool CombinerHelper::matchSelect(MachineInstr &MI, BuildFnTy &MatchInfo) { if (tryFoldBoolSelectToLogic(Select, MatchInfo)) return true; - if (tryFoldSelectOfBinOps(Select, MatchInfo)) - return true; - return false; } diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir index c5a3490221b66..be2de620fa456 100644 --- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir @@ -544,154 +544,3 @@ body: | %ext:_(s32) = G_ANYEXT %sel $w0 = COPY %ext(s32) ... ---- -# select cond, and(x, y), and(z, y) --> and (select cond, x, z), y -name: select_cond_and_x_y_and_z_y_and_select_x_z_y -body: | - bb.1: - liveins: $x0, $x1, $x2 - ; CHECK-LABEL: name: select_cond_and_x_y_and_z_y_and_select_x_z_y - ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2 - ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x3 - ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) - ; CHECK-NEXT: %a:_(s8) = G_TRUNC [[COPY1]](s64) - ; CHECK-NEXT: %b:_(s8) = G_TRUNC [[COPY2]](s64) - ; CHECK-NEXT: %d:_(s8) = G_TRUNC [[COPY3]](s64) - ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s8) = G_SELECT %c(s1), %a, %d - ; CHECK-NEXT: %sel:_(s8) = G_AND [[SELECT]], %b - ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s8) - ; CHECK-NEXT: $w0 = COPY %ext(s32) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s64) = COPY $x2 - %3:_(s64) = COPY $x3 - %4:_(s64) = COPY $x4 - %c:_(s1) = G_TRUNC %0 - %a:_(s8) = G_TRUNC %1 - %b:_(s8) = G_TRUNC %2 - %d:_(s8) = G_TRUNC %3 - %e:_(s8) = G_TRUNC %4 - %and1:_(s8) = G_AND %a, %b - %and2:_(s8) = G_AND %d, %b - %sel:_(s8) = G_SELECT %c, %and1, %and2 - %ext:_(s32) = G_ANYEXT %sel - $w0 = COPY %ext(s32) -... ---- -# select cond, xor(x, y), xor(x, z) --> xor x, select, x, z) -name: select_cond_xor_x_y_xor_x_z_xor_x__select_x_y -body: | - bb.1: - liveins: $x0, $x1, $x2 - ; CHECK-LABEL: name: select_cond_xor_x_y_xor_x_z_xor_x__select_x_y - ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x3 - ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x4 - ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) - ; CHECK-NEXT: %a:_(s8) = G_TRUNC [[COPY1]](s64) - ; CHECK-NEXT: %d:_(s8) = G_TRUNC [[COPY2]](s64) - ; CHECK-NEXT: %e:_(s8) = G_TRUNC [[COPY3]](s64) - ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s8) = G_SELECT %c(s1), %e, %d - ; CHECK-NEXT: %sel:_(s8) = G_XOR %a, [[SELECT]] - ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s8) - ; CHECK-NEXT: $w0 = COPY %ext(s32) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s64) = COPY $x2 - %3:_(s64) = COPY $x3 - %4:_(s64) = COPY $x4 - %c:_(s1) = G_TRUNC %0 - %a:_(s8) = G_TRUNC %1 - %b:_(s8) = G_TRUNC %2 - %d:_(s8) = G_TRUNC %3 - %e:_(s8) = G_TRUNC %4 - %xor1:_(s8) = G_XOR %a, %e - %xor2:_(s8) = G_XOR %a, %d - %sel:_(s8) = G_SELECT %c, %xor1, %xor2 - %ext:_(s32) = G_ANYEXT %sel - $w0 = COPY %ext(s32) -... ---- -# negative test select cond, and(x, y), or(z, a) --> failed -name: select_cond_and_x_y_or_z_a_failed -body: | - bb.1: - liveins: $x0, $x1, $x2 - ; CHECK-LABEL: name: select_cond_and_x_y_or_z_a_failed - ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x2 - ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x3 - ; CHECK-NEXT: [[COPY4:%[0-9]+]]:_(s64) = COPY $x4 - ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) - ; CHECK-NEXT: %a:_(s8) = G_TRUNC [[COPY1]](s64) - ; CHECK-NEXT: %b:_(s8) = G_TRUNC [[COPY2]](s64) - ; CHECK-NEXT: %d:_(s8) = G_TRUNC [[COPY3]](s64) - ; CHECK-NEXT: %e:_(s8) = G_TRUNC [[COPY4]](s64) - ; CHECK-NEXT: %and1:_(s8) = G_AND %a, %b - ; CHECK-NEXT: %or2:_(s8) = G_OR %e, %d - ; CHECK-NEXT: %sel:_(s8) = G_SELECT %c(s1), %and1, %or2 - ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s8) - ; CHECK-NEXT: $w0 = COPY %ext(s32) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s64) = COPY $x2 - %3:_(s64) = COPY $x3 - %4:_(s64) = COPY $x4 - %c:_(s1) = G_TRUNC %0 - %a:_(s8) = G_TRUNC %1 - %b:_(s8) = G_TRUNC %2 - %d:_(s8) = G_TRUNC %3 - %e:_(s8) = G_TRUNC %4 - %and1:_(s8) = G_AND %a, %b - %or2:_(s8) = G_OR %e, %d - %sel:_(s8) = G_SELECT %c, %and1, %or2 - %ext:_(s32) = G_ANYEXT %sel - $w0 = COPY %ext(s32) -... ---- -# flags test select cond, xor(x, y), xor(x, z) --> xor x, select, cond, x, z) -name: flags_select_cond_xor_x_y_xor_x_z_xor_x__select_cond_x_y -body: | - bb.1: - liveins: $x0, $x1, $x2 - ; CHECK-LABEL: name: flags_select_cond_xor_x_y_xor_x_z_xor_x__select_cond_x_y - ; CHECK: liveins: $x0, $x1, $x2 - ; CHECK-NEXT: {{ $}} - ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0 - ; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1 - ; CHECK-NEXT: [[COPY2:%[0-9]+]]:_(s64) = COPY $x3 - ; CHECK-NEXT: [[COPY3:%[0-9]+]]:_(s64) = COPY $x4 - ; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64) - ; CHECK-NEXT: %a:_(s8) = G_TRUNC [[COPY1]](s64) - ; CHECK-NEXT: %d:_(s8) = G_TRUNC [[COPY2]](s64) - ; CHECK-NEXT: %e:_(s8) = G_TRUNC [[COPY3]](s64) - ; CHECK-NEXT: [[SELECT:%[0-9]+]]:_(s8) = ninf exact G_SELECT %c(s1), %e, %d - ; CHECK-NEXT: %sel:_(s8) = ninf arcp exact G_XOR %a, [[SELECT]] - ; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s8) - ; CHECK-NEXT: $w0 = COPY %ext(s32) - %0:_(s64) = COPY $x0 - %1:_(s64) = COPY $x1 - %2:_(s64) = COPY $x2 - %3:_(s64) = COPY $x3 - %4:_(s64) = COPY $x4 - %c:_(s1) = G_TRUNC %0 - %a:_(s8) = G_TRUNC %1 - %b:_(s8) = G_TRUNC %2 - %d:_(s8) = G_TRUNC %3 - %e:_(s8) = G_TRUNC %4 - %xor1:_(s8) = nsz arcp nsw G_XOR %a, %e - %xor2:_(s8) = nnan arcp nuw G_XOR %a, %d - %sel:_(s8) = ninf exact G_SELECT %c, %xor1, %xor2 - %ext:_(s32) = G_ANYEXT %sel - $w0 = COPY %ext(s32) -...