Skip to content

Commit 85a1116

Browse files
committed
Add support for checking and dropping poison-generating flags
1 parent 2184160 commit 85a1116

File tree

3 files changed

+91
-2
lines changed

3 files changed

+91
-2
lines changed

llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,83 @@ class GenericMachineInstr : public MachineInstr {
3434
static bool classof(const MachineInstr *MI) {
3535
return isPreISelGenericOpcode(MI->getOpcode());
3636
}
37+
38+
bool hasPoisonGeneratingFlags() const {
39+
switch (getOpcode()) {
40+
case TargetOpcode::G_ADD:
41+
case TargetOpcode::G_SUB:
42+
case TargetOpcode::G_MUL:
43+
case TargetOpcode::G_SHL:
44+
case TargetOpcode::G_TRUNC:
45+
return getFlag(NoUWrap) || getFlag(NoSWrap);
46+
47+
case TargetOpcode::G_UDIV:
48+
case TargetOpcode::G_SDIV:
49+
case TargetOpcode::G_ASHR:
50+
case TargetOpcode::G_LSHR:
51+
return getFlag(IsExact);
52+
53+
case TargetOpcode::G_OR:
54+
return getFlag(Disjoint);
55+
56+
case TargetOpcode::G_UITOFP:
57+
case TargetOpcode::G_ZEXT:
58+
return getFlag(NonNeg);
59+
60+
case TargetOpcode::G_FNEG:
61+
case TargetOpcode::G_FADD:
62+
case TargetOpcode::G_FSUB:
63+
case TargetOpcode::G_FMUL:
64+
case TargetOpcode::G_FDIV:
65+
case TargetOpcode::G_FREM:
66+
case TargetOpcode::G_FCMP:
67+
return getFlag(FmNoNans) || getFlag(FmNoInfs);
68+
69+
default:
70+
return false;
71+
}
72+
}
73+
74+
void dropPoisonGeneratingFlags() {
75+
switch (getOpcode()) {
76+
case TargetOpcode::G_ADD:
77+
case TargetOpcode::G_SUB:
78+
case TargetOpcode::G_MUL:
79+
case TargetOpcode::G_SHL:
80+
case TargetOpcode::G_TRUNC:
81+
clearFlag(NoUWrap);
82+
clearFlag(NoSWrap);
83+
break;
84+
85+
case TargetOpcode::G_UDIV:
86+
case TargetOpcode::G_SDIV:
87+
case TargetOpcode::G_ASHR:
88+
case TargetOpcode::G_LSHR:
89+
clearFlag(IsExact);
90+
break;
91+
92+
case TargetOpcode::G_OR:
93+
clearFlag(Disjoint);
94+
break;
95+
96+
case TargetOpcode::G_UITOFP:
97+
case TargetOpcode::G_ZEXT:
98+
clearFlag(NonNeg);
99+
break;
100+
101+
case TargetOpcode::G_FNEG:
102+
case TargetOpcode::G_FADD:
103+
case TargetOpcode::G_FSUB:
104+
case TargetOpcode::G_FMUL:
105+
case TargetOpcode::G_FDIV:
106+
case TargetOpcode::G_FREM:
107+
case TargetOpcode::G_FCMP:
108+
clearFlag(FmNoNans);
109+
clearFlag(FmNoInfs);
110+
break;
111+
}
112+
assert(!hasPoisonGeneratingFlags());
113+
}
37114
};
38115

39116
/// Provides common memory operand functionality.

llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,13 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
234234

235235
MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp);
236236
// Avoid trying to fold G_PHI, G_UNMERGE_VALUES, G_FREEZE (the latter is
237-
// handled by idempotent_prop)
237+
// handled by idempotent_prop).
238238
if (!OrigDef || OrigDef->isPHI() || isa<GUnmerge>(OrigDef) ||
239239
isa<GFreeze>(OrigDef))
240240
return false;
241241

242-
if (canCreateUndefOrPoison(OrigOp, MRI))
242+
if (canCreateUndefOrPoison(OrigOp, MRI,
243+
/*ConsiderFlagsAndMetadata*/ false))
243244
return false;
244245

245246
std::optional<MachineOperand> MaybePoisonOperand;
@@ -258,6 +259,8 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
258259
return false;
259260
}
260261

262+
cast<GenericMachineInstr>(OrigDef)->dropPoisonGeneratingFlags();
263+
261264
// Eliminate freeze if all operands are guaranteed non-poison.
262265
if (!MaybePoisonOperand) {
263266
MatchInfo = [=](MachineIRBuilder &B) { MRI.replaceRegWith(DstOp, OrigOp); };

llvm/lib/CodeGen/GlobalISel/Utils.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1733,6 +1733,15 @@ static bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI,
17331733
UndefPoisonKind Kind) {
17341734
MachineInstr *RegDef = MRI.getVRegDef(Reg);
17351735

1736+
if (auto *GMI = dyn_cast<GenericMachineInstr>(RegDef)) {
1737+
if (ConsiderFlagsAndMetadata && includesPoison(Kind) &&
1738+
GMI->hasPoisonGeneratingFlags())
1739+
return true;
1740+
}
1741+
// Conservatively return true.
1742+
else
1743+
return true;
1744+
17361745
switch (RegDef->getOpcode()) {
17371746
case TargetOpcode::G_FREEZE:
17381747
return false;

0 commit comments

Comments
 (0)