-
Notifications
You must be signed in to change notification settings - Fork 10.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[GlobalIsel] Combine select of binops #76763
Conversation
@llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-llvm-globalisel Author: Thorsten Schütt (tschuett) ChangesFull diff: https://github.com/llvm/llvm-project/pull/76763.diff 4 Files Affected:
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index dcc1a4580b14a2..f3b68623596c46 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -910,6 +910,9 @@ 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 6ab1d4550c51ca..21d98d30356c93 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -558,6 +558,109 @@ 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 8b15bdb0aca30b..102b49c48460b1 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -6390,8 +6390,7 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
if (TrueValue.isZero() && FalseValue.isOne()) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Inner = MRI.createGenericVirtualRegister(CondTy);
- B.buildNot(Inner, Cond);
+ auto Inner = B.buildNot(CondTy, Cond);
B.buildZExtOrTrunc(Dest, Inner);
};
return true;
@@ -6401,8 +6400,7 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
if (TrueValue.isZero() && FalseValue.isAllOnes()) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Inner = MRI.createGenericVirtualRegister(CondTy);
- B.buildNot(Inner, Cond);
+ auto Inner = B.buildNot(CondTy, Cond);
B.buildSExtOrTrunc(Dest, Inner);
};
return true;
@@ -6412,8 +6410,7 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
if (TrueValue - 1 == FalseValue) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Inner = MRI.createGenericVirtualRegister(TrueTy);
- B.buildZExtOrTrunc(Inner, Cond);
+ auto Inner = B.buildZExtOrTrunc(TrueTy, Cond);
B.buildAdd(Dest, Inner, False);
};
return true;
@@ -6423,8 +6420,7 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
if (TrueValue + 1 == FalseValue) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Inner = MRI.createGenericVirtualRegister(TrueTy);
- B.buildSExtOrTrunc(Inner, Cond);
+ auto Inner = B.buildSExtOrTrunc(TrueTy, Cond);
B.buildAdd(Dest, Inner, False);
};
return true;
@@ -6434,8 +6430,7 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
if (TrueValue.isPowerOf2() && FalseValue.isZero()) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Inner = MRI.createGenericVirtualRegister(TrueTy);
- B.buildZExtOrTrunc(Inner, Cond);
+ auto Inner = B.buildZExtOrTrunc(TrueTy, Cond);
// The shift amount must be scalar.
LLT ShiftTy = TrueTy.isVector() ? TrueTy.getElementType() : TrueTy;
auto ShAmtC = B.buildConstant(ShiftTy, TrueValue.exactLogBase2());
@@ -6447,8 +6442,7 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
if (TrueValue.isAllOnes()) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Inner = MRI.createGenericVirtualRegister(TrueTy);
- B.buildSExtOrTrunc(Inner, Cond);
+ auto Inner = B.buildSExtOrTrunc(TrueTy, Cond);
B.buildOr(Dest, Inner, False, Flags);
};
return true;
@@ -6458,10 +6452,8 @@ bool CombinerHelper::tryFoldSelectOfConstants(GSelect *Select,
if (FalseValue.isAllOnes()) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Not = MRI.createGenericVirtualRegister(CondTy);
- B.buildNot(Not, Cond);
- Register Inner = MRI.createGenericVirtualRegister(TrueTy);
- B.buildSExtOrTrunc(Inner, Not);
+ auto Not = B.buildNot(CondTy, Cond);
+ auto Inner = B.buildSExtOrTrunc(TrueTy, Not);
B.buildOr(Dest, Inner, True, Flags);
};
return true;
@@ -6496,8 +6488,7 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
if ((Cond == True) || isOneOrOneSplat(True, /* AllowUndefs */ true)) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Ext = MRI.createGenericVirtualRegister(TrueTy);
- B.buildZExtOrTrunc(Ext, Cond);
+ auto Ext = B.buildZExtOrTrunc(TrueTy, Cond);
B.buildOr(DstReg, Ext, False, Flags);
};
return true;
@@ -6508,8 +6499,7 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
if ((Cond == False) || isZeroOrZeroSplat(False, /* AllowUndefs */ true)) {
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
- Register Ext = MRI.createGenericVirtualRegister(TrueTy);
- B.buildZExtOrTrunc(Ext, Cond);
+ auto Ext = B.buildZExtOrTrunc(TrueTy, Cond);
B.buildAnd(DstReg, Ext, True);
};
return true;
@@ -6520,11 +6510,9 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
// First the not.
- Register Inner = MRI.createGenericVirtualRegister(CondTy);
- B.buildNot(Inner, Cond);
+ auto Inner = B.buildNot(CondTy, Cond);
// Then an ext to match the destination register.
- Register Ext = MRI.createGenericVirtualRegister(TrueTy);
- B.buildZExtOrTrunc(Ext, Inner);
+ auto Ext = B.buildZExtOrTrunc(TrueTy, Inner);
B.buildOr(DstReg, Ext, True, Flags);
};
return true;
@@ -6535,11 +6523,9 @@ bool CombinerHelper::tryFoldBoolSelectToLogic(GSelect *Select,
MatchInfo = [=](MachineIRBuilder &B) {
B.setInstrAndDebugLoc(*Select);
// First the not.
- Register Inner = MRI.createGenericVirtualRegister(CondTy);
- B.buildNot(Inner, Cond);
+ auto Inner = B.buildNot(CondTy, Cond);
// Then an ext to match the destination register.
- Register Ext = MRI.createGenericVirtualRegister(TrueTy);
- B.buildZExtOrTrunc(Ext, Inner);
+ auto Ext = B.buildZExtOrTrunc(TrueTy, Inner);
B.buildAnd(DstReg, Ext, False);
};
return true;
@@ -6548,6 +6534,52 @@ 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<GBinOp>(True, MRI);
+ GBinOp *RHS = getOpcodeDef<GBinOp>(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();
+ 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());
+ 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());
+ 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<GSelect>(&MI);
@@ -6557,5 +6589,8 @@ 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 be2de620fa456c..7644443f53dc68 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
@@ -544,3 +544,77 @@ body: |
%ext:_(s32) = G_ANYEXT %sel
$w0 = COPY %ext(s32)
...
+---
+# select cond, and(x, y), and(z, y) --> and (select, 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)
+...
|
This one has a limited effect. I fixed the coding style violations from the last PR. |
Register getRHSReg() const { return getReg(2); } | ||
|
||
static bool classof(const MachineInstr *MI) { | ||
switch (MI->getOpcode()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you implement this in terms of GIntBinOp::classof and GFBinOp::classof to avoid listing the opcodes in multiple places?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to suggest that too but it won't compile due to not yet seeing the definition of GIntBinOp
when parsing this class.
return false; | ||
|
||
// Note that there are no constraints on CondTy. | ||
unsigned Flags = LHS->getFlags() & RHS->getFlags(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't consider the flags on the select itself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The DAG combiner intersects the flags of the binops and ignores the select flags.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's also suboptimal for the DAG combiner. I think it should be (LHS & RHS) | Select. Does InstCombine preserve these?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's also quite likely that code was never properly updated for select gaining flags. It was a relatively recent IR change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NewBinOp->setFlags(N1->getFlags());
NewBinOp->intersectFlagsWith(N2->getFlags());
It ignores the select flags. I updated my code locally.
%e:_(s8) = G_TRUNC %4 | ||
%xor1:_(s8) = G_XOR %a, %e | ||
%xor2:_(s8) = G_XOR %a, %d | ||
%sel:_(s8) = G_SELECT %c, %xor1, %xor2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could use negative test with mismatched opcodes. Also missing tests for the flag handling. Precommitting tests would also be good
@@ -544,3 +544,77 @@ body: | | |||
%ext:_(s32) = G_ANYEXT %sel | |||
$w0 = COPY %ext(s32) | |||
... | |||
--- | |||
# select cond, and(x, y), and(z, y) --> and (select, x, z), y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: comment missing cond
on RHS: --> and (select cond, x, z), y
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Need to address Matt's comment.
Register getRHSReg() const { return getReg(2); } | ||
|
||
static bool classof(const MachineInstr *MI) { | ||
switch (MI->getOpcode()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to suggest that too but it won't compile due to not yet seeing the definition of GIntBinOp
when parsing this class.
Please review changes (C++ and mir) regarding flag handling. |
return false; | ||
|
||
// Note that there are no constraints on CondTy. | ||
unsigned Flags = (LHS->getFlags() & RHS->getFlags()) | Select->getFlags(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line differs from the Dag combiner.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have split this by matching the DAG behavior in the initial commit but doesn't really matter. I think this is OK but would be nice to have alive verify
MatchInfo = [=](MachineIRBuilder &B) { | ||
B.setInstrAndDebugLoc(*Select); | ||
auto Sel = B.buildSelect(DstTy, Cond, LHS->getLHSReg(), RHS->getLHSReg(), | ||
Select->getFlags()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And Flags are added to selects.
; 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]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
G_XOR has arcp because both ors had it. And it got exact from the select.
%d:_(s8) = G_TRUNC %3 | ||
%e:_(s8) = G_TRUNC %4 | ||
%and1:_(s8) = G_AND %a, %b | ||
%or2:_(s8) = G_OR %e, %d |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This failed because and and or.
this lit test is now taking a very long time after this patch landed relevant cmake settings: |
@jhuber6 @jplehr this may also be failing in staging libc bot https://lab.llvm.org/staging/#/builders/134 |
I had also issues with this test. There is also a GH issue: #76821. |
The file was not changed by this PR and there is no |
It's also exhausting memory when |
I reverted the commit. |
This reverts commit 1687555.
No description provided.