[llvm] [GISel][CombinerHelper] Push freeze through non-poison-producing operands (PR #90618)
Dhruv Chawla via llvm-commits
llvm-commits at lists.llvm.org
Tue May 21 02:39:05 PDT 2024
https://github.com/dc03-work updated https://github.com/llvm/llvm-project/pull/90618
>From 11568391430bcff551a19bbcf3e916605437a050 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Tue, 30 Apr 2024 17:04:00 +0530
Subject: [PATCH 1/9] [GISel][CombinerHelper] Push freeze through
non-poison-producing operands
This combine matches the existing fold in InstCombine, i.e.
InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating.
It tries to push freeze through an operand if the operand has only one
maybe-poison operand and all other operands are guaranteed non-poison.
This is beneficial because it can potentially enable other optimizations
to occur that would otherwise be blocked because of the freeze.
---
.../llvm/CodeGen/GlobalISel/CombinerHelper.h | 2 +
.../include/llvm/Target/GlobalISel/Combine.td | 10 +++-
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 59 +++++++++++++++++++
llvm/lib/CodeGen/GlobalISel/Utils.cpp | 17 +++++-
llvm/lib/Target/AArch64/AArch64Combine.td | 3 +-
.../AArch64/GlobalISel/combine-select.mir | 42 ++++++-------
llvm/test/CodeGen/AArch64/pr58431.ll | 4 +-
7 files changed, 111 insertions(+), 26 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index a9a33c7617d7d..53eb31c12f349 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -869,6 +869,8 @@ class CombinerHelper {
/// Combine insert vector element OOB.
bool matchInsertVectorElementOOB(MachineInstr &MI, BuildFnTy &MatchInfo);
+ bool matchFreezeOfSingleMaybePoisonOperand(MachineInstr &MI, BuildFnTy &MatchInfo);
+
private:
/// Checks for legality of an indexed variant of \p LdSt.
bool isIndexedLoadStoreLegal(GLoadStore &LdSt) const;
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 5d4b5a2479f6a..29f8cc4da5f95 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -220,6 +220,13 @@ def idempotent_prop : GICombineRule<
(match (idempotent_prop_frags $dst, $src)),
(apply (GIReplaceReg $dst, $src))>;
+// Convert freeze(Op(Op0, NonPoisonOps...)) to Op(freeze(Op0), NonPoisonOps...)
+// when Op0 is not guaranteed non-poison
+def push_freeze_to_prevent_poison_propagation : GICombineRule<
+ (defs root:$root, build_fn_matchinfo:$matchinfo),
+ (match (wip_match_opcode G_FREEZE):$root,
+ [{ return Helper.matchFreezeOfSingleMaybePoisonOperand(*${root}, ${matchinfo}); }]),
+ (apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
def extending_loads : GICombineRule<
(defs root:$root, extending_load_matchdata:$matchinfo),
@@ -1713,7 +1720,8 @@ def all_combines : GICombineGroup<[trivial_combines, vector_ops_combines,
sub_add_reg, select_to_minmax, redundant_binop_in_equality,
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
combine_concat_vector, double_icmp_zero_and_or_combine, match_addos,
- sext_trunc, zext_trunc, combine_shuffle_concat]>;
+ sext_trunc, zext_trunc, combine_shuffle_concat,
+ push_freeze_to_prevent_poison_propagation]>;
// A combine group used to for prelegalizer combiners at -O0. The combines in
// this group have been selected based on experiments to balance code size and
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 22eb4a3e0d7cb..3ed08b1528c9f 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -223,6 +223,64 @@ void CombinerHelper::applyCombineCopy(MachineInstr &MI) {
replaceRegWith(MRI, DstReg, SrcReg);
}
+bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
+ MachineInstr &MI, BuildFnTy &MatchInfo) {
+ // Ported from InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating
+ Register DstOp = MI.getOperand(0).getReg();
+ Register OrigOp = MI.getOperand(1).getReg();
+
+ if (OrigOp.isPhysical() || !MRI.hasOneNonDBGUse(OrigOp))
+ return false;
+
+ MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp);
+ // Avoid trying to fold G_PHI, G_UNMERGE_VALUES, G_FREEZE (the latter is
+ // handled by idempotent_prop)
+ if (!OrigDef || OrigDef->isPHI() || isa<GUnmerge>(OrigDef) ||
+ isa<GFreeze>(OrigDef))
+ return false;
+
+ if (canCreateUndefOrPoison(OrigOp, MRI))
+ return false;
+
+ std::optional<MachineOperand> MaybePoisonOperand = std::nullopt;
+ for (MachineOperand &Operand : OrigDef->uses()) {
+ // Avoid working on non-register operands or physical registers.
+ if (!Operand.isReg() || Operand.getReg().isPhysical())
+ return false;
+
+ if (isGuaranteedNotToBeUndefOrPoison(Operand.getReg(), MRI))
+ continue;
+
+ if (!MaybePoisonOperand)
+ MaybePoisonOperand = Operand;
+ // We have more than one maybe-poison operand. Moving the freeze is unsafe.
+ else
+ return false;
+ }
+
+ // Eliminate freeze if all operands are guaranteed non-poison
+ if (!MaybePoisonOperand) {
+ MatchInfo = [=](MachineIRBuilder &B) { MRI.replaceRegWith(DstOp, OrigOp); };
+ return true;
+ }
+
+ if (!MaybePoisonOperand->isReg())
+ return false;
+
+ Register MaybePoisonOperandReg = MaybePoisonOperand->getReg();
+ LLT MaybePoisonOperandRegTy = MRI.getType(MaybePoisonOperandReg);
+
+ MatchInfo = [=](MachineIRBuilder &B) mutable {
+ auto Reg = MRI.createGenericVirtualRegister(MaybePoisonOperandRegTy);
+ B.setInsertPt(*OrigDef->getParent(), OrigDef->getIterator());
+ B.buildFreeze(Reg, MaybePoisonOperandReg);
+ replaceRegOpWith(
+ MRI, *OrigDef->findRegisterUseOperand(MaybePoisonOperandReg, TRI), Reg);
+ replaceRegWith(MRI, DstOp, OrigOp);
+ };
+ return true;
+}
+
bool CombinerHelper::matchCombineConcatVectors(MachineInstr &MI,
SmallVector<Register> &Ops) {
assert(MI.getOpcode() == TargetOpcode::G_CONCAT_VECTORS &&
@@ -3060,6 +3118,7 @@ bool CombinerHelper::matchHoistLogicOpWithSameOpcodeHands(
MachineInstr *RightHandInst = getDefIgnoringCopies(RHSReg, MRI);
if (!LeftHandInst || !RightHandInst)
return false;
+
unsigned HandOpcode = LeftHandInst->getOpcode();
if (HandOpcode != RightHandInst->getOpcode())
return false;
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index cd5dc0e01ed0e..0085074714d44 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -1749,6 +1749,8 @@ static bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI,
case TargetOpcode::G_FREEZE:
return false;
default:
+ if (isa<GCastOp>(RegDef) || isa<GBinOp>(RegDef))
+ return false;
return true;
}
}
@@ -1762,13 +1764,26 @@ static bool isGuaranteedNotToBeUndefOrPoison(Register Reg,
MachineInstr *RegDef = MRI.getVRegDef(Reg);
+ auto OpCheck = [&](MachineOperand &Operand) {
+ if (!Operand.isReg())
+ return true;
+
+ return isGuaranteedNotToBeUndefOrPoison(Operand.getReg(), MRI, Depth + 1,
+ Kind);
+ };
+
switch (RegDef->getOpcode()) {
case TargetOpcode::G_FREEZE:
return true;
case TargetOpcode::G_IMPLICIT_DEF:
return !includesUndef(Kind);
default:
- return false;
+ GenericMachineInstr *Opr = dyn_cast<GBinOp>(RegDef);
+ if (!Opr)
+ Opr = dyn_cast<GCastOp>(RegDef);
+
+ return Opr && !::llvm::canCreateUndefOrPoison(Reg, MRI) &&
+ all_of(Opr->operands(), OpCheck);
}
}
diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index 10cad6d192440..7229d4fe52261 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -295,5 +295,6 @@ def AArch64PostLegalizerCombiner
ptr_add_immed_chain, overlapping_and,
split_store_zero_128, undef_combines,
select_to_minmax, or_to_bsp, combine_concat_vector,
- commute_constant_to_rhs]> {
+ commute_constant_to_rhs,
+ push_freeze_to_prevent_poison_propagation]> {
}
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
index 353c1550d6974..074d4ecbd8785 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-select.mir
@@ -117,9 +117,9 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x2
; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64)
- ; CHECK-NEXT: %f:_(s1) = G_TRUNC [[COPY1]](s64)
- ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE %f
- ; CHECK-NEXT: %sel:_(s1) = G_OR %c, [[FREEZE]]
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]]
+ ; CHECK-NEXT: %f:_(s1) = G_TRUNC [[FREEZE]](s64)
+ ; CHECK-NEXT: %sel:_(s1) = G_OR %c, %f
; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1)
; CHECK-NEXT: $w0 = COPY %ext(s32)
%0:_(s64) = COPY $x0
@@ -144,9 +144,9 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x2
; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64)
- ; CHECK-NEXT: %f:_(s1) = G_TRUNC [[COPY1]](s64)
- ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE %f
- ; CHECK-NEXT: %sel:_(s1) = G_OR %c, [[FREEZE]]
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]]
+ ; CHECK-NEXT: %f:_(s1) = G_TRUNC [[FREEZE]](s64)
+ ; CHECK-NEXT: %sel:_(s1) = G_OR %c, %f
; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1)
; CHECK-NEXT: $w0 = COPY %ext(s32)
%0:_(s64) = COPY $x0
@@ -172,9 +172,9 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(<2 x s32>) = COPY $d0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(<2 x s32>) = COPY $d2
; CHECK-NEXT: %c:_(<2 x s1>) = G_TRUNC [[COPY]](<2 x s32>)
- ; CHECK-NEXT: %f:_(<2 x s1>) = G_TRUNC [[COPY1]](<2 x s32>)
- ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(<2 x s1>) = G_FREEZE %f
- ; CHECK-NEXT: %sel:_(<2 x s1>) = G_OR %c, [[FREEZE]]
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(<2 x s32>) = G_FREEZE [[COPY1]]
+ ; CHECK-NEXT: %f:_(<2 x s1>) = G_TRUNC [[FREEZE]](<2 x s32>)
+ ; CHECK-NEXT: %sel:_(<2 x s1>) = G_OR %c, %f
; CHECK-NEXT: %ext:_(<2 x s32>) = G_ANYEXT %sel(<2 x s1>)
; CHECK-NEXT: $d0 = COPY %ext(<2 x s32>)
%0:_(<2 x s32>) = COPY $d0
@@ -201,9 +201,9 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64)
- ; CHECK-NEXT: %t:_(s1) = G_TRUNC [[COPY1]](s64)
- ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE %t
- ; CHECK-NEXT: %sel:_(s1) = G_AND %c, [[FREEZE]]
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]]
+ ; CHECK-NEXT: %t:_(s1) = G_TRUNC [[FREEZE]](s64)
+ ; CHECK-NEXT: %sel:_(s1) = G_AND %c, %t
; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1)
; CHECK-NEXT: $w0 = COPY %ext(s32)
%0:_(s64) = COPY $x0
@@ -229,9 +229,9 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64)
- ; CHECK-NEXT: %t:_(s1) = G_TRUNC [[COPY1]](s64)
- ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE %t
- ; CHECK-NEXT: %sel:_(s1) = G_AND %c, [[FREEZE]]
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]]
+ ; CHECK-NEXT: %t:_(s1) = G_TRUNC [[FREEZE]](s64)
+ ; CHECK-NEXT: %sel:_(s1) = G_AND %c, %t
; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1)
; CHECK-NEXT: $w0 = COPY %ext(s32)
%0:_(s64) = COPY $x0
@@ -257,11 +257,11 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x1
; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64)
- ; CHECK-NEXT: %t:_(s1) = G_TRUNC [[COPY1]](s64)
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]]
+ ; CHECK-NEXT: %t:_(s1) = G_TRUNC [[FREEZE]](s64)
; CHECK-NEXT: %one:_(s1) = G_CONSTANT i1 true
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR %c, %one
- ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE %t
- ; CHECK-NEXT: %sel:_(s1) = G_OR [[XOR]], [[FREEZE]]
+ ; CHECK-NEXT: %sel:_(s1) = G_OR [[XOR]], %t
; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1)
; CHECK-NEXT: $w0 = COPY %ext(s32)
%0:_(s64) = COPY $x0
@@ -287,11 +287,11 @@ body: |
; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
; CHECK-NEXT: [[COPY1:%[0-9]+]]:_(s64) = COPY $x2
; CHECK-NEXT: %c:_(s1) = G_TRUNC [[COPY]](s64)
- ; CHECK-NEXT: %f:_(s1) = G_TRUNC [[COPY1]](s64)
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY1]]
+ ; CHECK-NEXT: %f:_(s1) = G_TRUNC [[FREEZE]](s64)
; CHECK-NEXT: [[C:%[0-9]+]]:_(s1) = G_CONSTANT i1 true
; CHECK-NEXT: [[XOR:%[0-9]+]]:_(s1) = G_XOR %c, [[C]]
- ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s1) = G_FREEZE %f
- ; CHECK-NEXT: %sel:_(s1) = G_AND [[XOR]], [[FREEZE]]
+ ; CHECK-NEXT: %sel:_(s1) = G_AND [[XOR]], %f
; CHECK-NEXT: %ext:_(s32) = G_ANYEXT %sel(s1)
; CHECK-NEXT: $w0 = COPY %ext(s32)
%0:_(s64) = COPY $x0
diff --git a/llvm/test/CodeGen/AArch64/pr58431.ll b/llvm/test/CodeGen/AArch64/pr58431.ll
index dcd97597ae409..e87d8f7874d62 100644
--- a/llvm/test/CodeGen/AArch64/pr58431.ll
+++ b/llvm/test/CodeGen/AArch64/pr58431.ll
@@ -4,8 +4,8 @@
define i32 @f(i64 %0) {
; CHECK-LABEL: f:
; CHECK: // %bb.0:
-; CHECK-NEXT: mov w8, #10
-; CHECK-NEXT: mov w9, w0
+; CHECK-NEXT: mov w8, #10 // =0xa
+; CHECK-NEXT: and x9, x0, #0xffffffff
; CHECK-NEXT: udiv x10, x9, x8
; CHECK-NEXT: msub x0, x10, x8, x9
; CHECK-NEXT: // kill: def $w0 killed $w0 killed $x0
>From f26133b875d28535344f49b69227700aa8281afc Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Tue, 30 Apr 2024 20:32:39 +0530
Subject: [PATCH 2/9] Address reviewer comments
---
.../include/llvm/CodeGen/GlobalISel/CombinerHelper.h | 3 ++-
llvm/include/llvm/Target/GlobalISel/Combine.td | 4 ++--
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 12 ++++--------
3 files changed, 8 insertions(+), 11 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
index 53eb31c12f349..2111e82e1a99d 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/CombinerHelper.h
@@ -869,7 +869,8 @@ class CombinerHelper {
/// Combine insert vector element OOB.
bool matchInsertVectorElementOOB(MachineInstr &MI, BuildFnTy &MatchInfo);
- bool matchFreezeOfSingleMaybePoisonOperand(MachineInstr &MI, BuildFnTy &MatchInfo);
+ bool matchFreezeOfSingleMaybePoisonOperand(MachineInstr &MI,
+ BuildFnTy &MatchInfo);
private:
/// Checks for legality of an indexed variant of \p LdSt.
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 29f8cc4da5f95..3035201d4df18 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -224,8 +224,8 @@ def idempotent_prop : GICombineRule<
// when Op0 is not guaranteed non-poison
def push_freeze_to_prevent_poison_propagation : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
- (match (wip_match_opcode G_FREEZE):$root,
- [{ return Helper.matchFreezeOfSingleMaybePoisonOperand(*${root}, ${matchinfo}); }]),
+ (match (G_FREEZE $dst, $src):$root,
+ [{ return !isGuaranteedNotToBePoison(${src}.getReg(), MRI) && Helper.matchFreezeOfSingleMaybePoisonOperand(*${root}, ${matchinfo}); }]),
(apply [{ Helper.applyBuildFn(*${root}, ${matchinfo}); }])>;
def extending_loads : GICombineRule<
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index 3ed08b1528c9f..bf249c3dc1a75 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -242,10 +242,10 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
if (canCreateUndefOrPoison(OrigOp, MRI))
return false;
- std::optional<MachineOperand> MaybePoisonOperand = std::nullopt;
+ std::optional<MachineOperand> MaybePoisonOperand;
for (MachineOperand &Operand : OrigDef->uses()) {
- // Avoid working on non-register operands or physical registers.
- if (!Operand.isReg() || Operand.getReg().isPhysical())
+ // Avoid working on non-register operands.
+ if (!Operand.isReg())
return false;
if (isGuaranteedNotToBeUndefOrPoison(Operand.getReg(), MRI))
@@ -258,15 +258,12 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
return false;
}
- // Eliminate freeze if all operands are guaranteed non-poison
+ // Eliminate freeze if all operands are guaranteed non-poison.
if (!MaybePoisonOperand) {
MatchInfo = [=](MachineIRBuilder &B) { MRI.replaceRegWith(DstOp, OrigOp); };
return true;
}
- if (!MaybePoisonOperand->isReg())
- return false;
-
Register MaybePoisonOperandReg = MaybePoisonOperand->getReg();
LLT MaybePoisonOperandRegTy = MRI.getType(MaybePoisonOperandReg);
@@ -3118,7 +3115,6 @@ bool CombinerHelper::matchHoistLogicOpWithSameOpcodeHands(
MachineInstr *RightHandInst = getDefIgnoringCopies(RHSReg, MRI);
if (!LeftHandInst || !RightHandInst)
return false;
-
unsigned HandOpcode = LeftHandInst->getOpcode();
if (HandOpcode != RightHandInst->getOpcode())
return false;
>From 41464f045ca660f5ea5bc7f2edad6f50d951a9b3 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Wed, 1 May 2024 08:57:32 +0530
Subject: [PATCH 3/9] Add support for checking and dropping poison-generating
flags
---
.../CodeGen/GlobalISel/GenericMachineInstrs.h | 77 +++++++++++++++++++
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 7 +-
llvm/lib/CodeGen/GlobalISel/Utils.cpp | 9 +++
3 files changed, 91 insertions(+), 2 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index 2a3145b635e6c..ef4c307d6c4b1 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -34,6 +34,83 @@ class GenericMachineInstr : public MachineInstr {
static bool classof(const MachineInstr *MI) {
return isPreISelGenericOpcode(MI->getOpcode());
}
+
+ bool hasPoisonGeneratingFlags() const {
+ switch (getOpcode()) {
+ case TargetOpcode::G_ADD:
+ case TargetOpcode::G_SUB:
+ case TargetOpcode::G_MUL:
+ case TargetOpcode::G_SHL:
+ case TargetOpcode::G_TRUNC:
+ return getFlag(NoUWrap) || getFlag(NoSWrap);
+
+ case TargetOpcode::G_UDIV:
+ case TargetOpcode::G_SDIV:
+ case TargetOpcode::G_ASHR:
+ case TargetOpcode::G_LSHR:
+ return getFlag(IsExact);
+
+ case TargetOpcode::G_OR:
+ return getFlag(Disjoint);
+
+ case TargetOpcode::G_UITOFP:
+ case TargetOpcode::G_ZEXT:
+ return getFlag(NonNeg);
+
+ case TargetOpcode::G_FNEG:
+ case TargetOpcode::G_FADD:
+ case TargetOpcode::G_FSUB:
+ case TargetOpcode::G_FMUL:
+ case TargetOpcode::G_FDIV:
+ case TargetOpcode::G_FREM:
+ case TargetOpcode::G_FCMP:
+ return getFlag(FmNoNans) || getFlag(FmNoInfs);
+
+ default:
+ return false;
+ }
+ }
+
+ void dropPoisonGeneratingFlags() {
+ switch (getOpcode()) {
+ case TargetOpcode::G_ADD:
+ case TargetOpcode::G_SUB:
+ case TargetOpcode::G_MUL:
+ case TargetOpcode::G_SHL:
+ case TargetOpcode::G_TRUNC:
+ clearFlag(NoUWrap);
+ clearFlag(NoSWrap);
+ break;
+
+ case TargetOpcode::G_UDIV:
+ case TargetOpcode::G_SDIV:
+ case TargetOpcode::G_ASHR:
+ case TargetOpcode::G_LSHR:
+ clearFlag(IsExact);
+ break;
+
+ case TargetOpcode::G_OR:
+ clearFlag(Disjoint);
+ break;
+
+ case TargetOpcode::G_UITOFP:
+ case TargetOpcode::G_ZEXT:
+ clearFlag(NonNeg);
+ break;
+
+ case TargetOpcode::G_FNEG:
+ case TargetOpcode::G_FADD:
+ case TargetOpcode::G_FSUB:
+ case TargetOpcode::G_FMUL:
+ case TargetOpcode::G_FDIV:
+ case TargetOpcode::G_FREM:
+ case TargetOpcode::G_FCMP:
+ clearFlag(FmNoNans);
+ clearFlag(FmNoInfs);
+ break;
+ }
+ assert(!hasPoisonGeneratingFlags());
+ }
};
/// Provides common memory operand functionality.
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index bf249c3dc1a75..ecdf3ff27f574 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -234,12 +234,13 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp);
// Avoid trying to fold G_PHI, G_UNMERGE_VALUES, G_FREEZE (the latter is
- // handled by idempotent_prop)
+ // handled by idempotent_prop).
if (!OrigDef || OrigDef->isPHI() || isa<GUnmerge>(OrigDef) ||
isa<GFreeze>(OrigDef))
return false;
- if (canCreateUndefOrPoison(OrigOp, MRI))
+ if (canCreateUndefOrPoison(OrigOp, MRI,
+ /*ConsiderFlagsAndMetadata*/ false))
return false;
std::optional<MachineOperand> MaybePoisonOperand;
@@ -258,6 +259,8 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
return false;
}
+ cast<GenericMachineInstr>(OrigDef)->dropPoisonGeneratingFlags();
+
// Eliminate freeze if all operands are guaranteed non-poison.
if (!MaybePoisonOperand) {
MatchInfo = [=](MachineIRBuilder &B) { MRI.replaceRegWith(DstOp, OrigOp); };
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 0085074714d44..7c95100c78879 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -1745,6 +1745,15 @@ static bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI,
UndefPoisonKind Kind) {
MachineInstr *RegDef = MRI.getVRegDef(Reg);
+ if (auto *GMI = dyn_cast<GenericMachineInstr>(RegDef)) {
+ if (ConsiderFlagsAndMetadata && includesPoison(Kind) &&
+ GMI->hasPoisonGeneratingFlags())
+ return true;
+ }
+ // Conservatively return true.
+ else
+ return true;
+
switch (RegDef->getOpcode()) {
case TargetOpcode::G_FREEZE:
return false;
>From 1ae3bbb1d613f40bff93d16b1de90e6fcd4700f0 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Mon, 6 May 2024 10:03:48 +0530
Subject: [PATCH 4/9] Refactor flag checking/dropping code
---
.../CodeGen/GlobalISel/GenericMachineInstrs.h | 80 +++----------------
1 file changed, 10 insertions(+), 70 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index ef4c307d6c4b1..4552b8a8d59d3 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -36,79 +36,19 @@ class GenericMachineInstr : public MachineInstr {
}
bool hasPoisonGeneratingFlags() const {
- switch (getOpcode()) {
- case TargetOpcode::G_ADD:
- case TargetOpcode::G_SUB:
- case TargetOpcode::G_MUL:
- case TargetOpcode::G_SHL:
- case TargetOpcode::G_TRUNC:
- return getFlag(NoUWrap) || getFlag(NoSWrap);
-
- case TargetOpcode::G_UDIV:
- case TargetOpcode::G_SDIV:
- case TargetOpcode::G_ASHR:
- case TargetOpcode::G_LSHR:
- return getFlag(IsExact);
-
- case TargetOpcode::G_OR:
- return getFlag(Disjoint);
-
- case TargetOpcode::G_UITOFP:
- case TargetOpcode::G_ZEXT:
- return getFlag(NonNeg);
-
- case TargetOpcode::G_FNEG:
- case TargetOpcode::G_FADD:
- case TargetOpcode::G_FSUB:
- case TargetOpcode::G_FMUL:
- case TargetOpcode::G_FDIV:
- case TargetOpcode::G_FREM:
- case TargetOpcode::G_FCMP:
- return getFlag(FmNoNans) || getFlag(FmNoInfs);
-
- default:
- return false;
- }
+ return getFlag(NoUWrap) || getFlag(NoSWrap) || getFlag(IsExact) ||
+ getFlag(Disjoint) || getFlag(NonNeg) || getFlag(FmNoNans) ||
+ getFlag(FmNoInfs);
}
void dropPoisonGeneratingFlags() {
- switch (getOpcode()) {
- case TargetOpcode::G_ADD:
- case TargetOpcode::G_SUB:
- case TargetOpcode::G_MUL:
- case TargetOpcode::G_SHL:
- case TargetOpcode::G_TRUNC:
- clearFlag(NoUWrap);
- clearFlag(NoSWrap);
- break;
-
- case TargetOpcode::G_UDIV:
- case TargetOpcode::G_SDIV:
- case TargetOpcode::G_ASHR:
- case TargetOpcode::G_LSHR:
- clearFlag(IsExact);
- break;
-
- case TargetOpcode::G_OR:
- clearFlag(Disjoint);
- break;
-
- case TargetOpcode::G_UITOFP:
- case TargetOpcode::G_ZEXT:
- clearFlag(NonNeg);
- break;
-
- case TargetOpcode::G_FNEG:
- case TargetOpcode::G_FADD:
- case TargetOpcode::G_FSUB:
- case TargetOpcode::G_FMUL:
- case TargetOpcode::G_FDIV:
- case TargetOpcode::G_FREM:
- case TargetOpcode::G_FCMP:
- clearFlag(FmNoNans);
- clearFlag(FmNoInfs);
- break;
- }
+ clearFlag(NoUWrap);
+ clearFlag(NoSWrap);
+ clearFlag(IsExact);
+ clearFlag(Disjoint);
+ clearFlag(NonNeg);
+ clearFlag(FmNoNans);
+ clearFlag(FmNoInfs);
assert(!hasPoisonGeneratingFlags());
}
};
>From ecfbbe3dc53c8bd52d8b25ee6d1adb48ac918a68 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Tue, 14 May 2024 10:44:51 +0530
Subject: [PATCH 5/9] Rebase and address reviewer comments
---
.../CodeGen/GlobalISel/GenericMachineInstrs.h | 5 ++---
.../lib/CodeGen/GlobalISel/CombinerHelper.cpp | 22 +++++++++----------
llvm/lib/CodeGen/GlobalISel/Utils.cpp | 10 ++++-----
3 files changed, 17 insertions(+), 20 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index 4552b8a8d59d3..f3c729900f13d 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -36,9 +36,8 @@ class GenericMachineInstr : public MachineInstr {
}
bool hasPoisonGeneratingFlags() const {
- return getFlag(NoUWrap) || getFlag(NoSWrap) || getFlag(IsExact) ||
- getFlag(Disjoint) || getFlag(NonNeg) || getFlag(FmNoNans) ||
- getFlag(FmNoInfs);
+ return getFlags() & (NoUWrap | NoSWrap | IsExact | Disjoint | NonNeg |
+ FmNoNans | FmNoInfs);
}
void dropPoisonGeneratingFlags() {
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index ecdf3ff27f574..ede2bf88434fa 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -229,18 +229,16 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
Register DstOp = MI.getOperand(0).getReg();
Register OrigOp = MI.getOperand(1).getReg();
- if (OrigOp.isPhysical() || !MRI.hasOneNonDBGUse(OrigOp))
+ if (!MRI.hasOneNonDBGUse(OrigOp))
return false;
MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp);
- // Avoid trying to fold G_PHI, G_UNMERGE_VALUES, G_FREEZE (the latter is
- // handled by idempotent_prop).
- if (!OrigDef || OrigDef->isPHI() || isa<GUnmerge>(OrigDef) ||
- isa<GFreeze>(OrigDef))
+ // Avoid trying to fold G_PHI and G_UNMERGE_VALUES.
+ if (OrigDef->isPHI() || isa<GUnmerge>(OrigDef))
return false;
if (canCreateUndefOrPoison(OrigOp, MRI,
- /*ConsiderFlagsAndMetadata*/ false))
+ /*ConsiderFlagsAndMetadata=*/false))
return false;
std::optional<MachineOperand> MaybePoisonOperand;
@@ -254,9 +252,11 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
if (!MaybePoisonOperand)
MaybePoisonOperand = Operand;
- // We have more than one maybe-poison operand. Moving the freeze is unsafe.
- else
+ else {
+ // We have more than one maybe-poison operand. Moving the freeze is
+ // unsafe.
return false;
+ }
}
cast<GenericMachineInstr>(OrigDef)->dropPoisonGeneratingFlags();
@@ -271,11 +271,11 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
LLT MaybePoisonOperandRegTy = MRI.getType(MaybePoisonOperandReg);
MatchInfo = [=](MachineIRBuilder &B) mutable {
- auto Reg = MRI.createGenericVirtualRegister(MaybePoisonOperandRegTy);
B.setInsertPt(*OrigDef->getParent(), OrigDef->getIterator());
- B.buildFreeze(Reg, MaybePoisonOperandReg);
+ auto Freeze = B.buildFreeze(MaybePoisonOperandRegTy, MaybePoisonOperandReg);
replaceRegOpWith(
- MRI, *OrigDef->findRegisterUseOperand(MaybePoisonOperandReg, TRI), Reg);
+ MRI, *OrigDef->findRegisterUseOperand(MaybePoisonOperandReg, TRI),
+ Freeze.getReg(0));
replaceRegWith(MRI, DstOp, OrigOp);
};
return true;
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 7c95100c78879..741363e1d7733 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -1749,18 +1749,16 @@ static bool canCreateUndefOrPoison(Register Reg, const MachineRegisterInfo &MRI,
if (ConsiderFlagsAndMetadata && includesPoison(Kind) &&
GMI->hasPoisonGeneratingFlags())
return true;
- }
- // Conservatively return true.
- else
+ } else {
+ // Conservatively return true.
return true;
+ }
switch (RegDef->getOpcode()) {
case TargetOpcode::G_FREEZE:
return false;
default:
- if (isa<GCastOp>(RegDef) || isa<GBinOp>(RegDef))
- return false;
- return true;
+ return !isa<GCastOp>(RegDef) && !isa<GBinOp>(RegDef);
}
}
>From 4e17f8ed9210df7745834e42ebd5e70fee966c28 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Thu, 16 May 2024 17:21:11 +0530
Subject: [PATCH 6/9] Address reviewer comments
---
llvm/include/llvm/Target/GlobalISel/Combine.td | 4 ++--
llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp | 12 +++++++++---
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 3035201d4df18..34698f195615b 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -222,7 +222,7 @@ def idempotent_prop : GICombineRule<
// Convert freeze(Op(Op0, NonPoisonOps...)) to Op(freeze(Op0), NonPoisonOps...)
// when Op0 is not guaranteed non-poison
-def push_freeze_to_prevent_poison_propagation : GICombineRule<
+def push_freeze_to_prevent_poison_from_propagating : GICombineRule<
(defs root:$root, build_fn_matchinfo:$matchinfo),
(match (G_FREEZE $dst, $src):$root,
[{ return !isGuaranteedNotToBePoison(${src}.getReg(), MRI) && Helper.matchFreezeOfSingleMaybePoisonOperand(*${root}, ${matchinfo}); }]),
@@ -1721,7 +1721,7 @@ def all_combines : GICombineGroup<[trivial_combines, vector_ops_combines,
fsub_to_fneg, commute_constant_to_rhs, match_ands, match_ors,
combine_concat_vector, double_icmp_zero_and_or_combine, match_addos,
sext_trunc, zext_trunc, combine_shuffle_concat,
- push_freeze_to_prevent_poison_propagation]>;
+ push_freeze_to_prevent_poison_from_propagating]>;
// A combine group used to for prelegalizer combiners at -O0. The combines in
// this group have been selected based on experiments to balance code size and
diff --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index ede2bf88434fa..4cc602b5c8709 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -225,7 +225,7 @@ void CombinerHelper::applyCombineCopy(MachineInstr &MI) {
bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
MachineInstr &MI, BuildFnTy &MatchInfo) {
- // Ported from InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating
+ // Ported from InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating.
Register DstOp = MI.getOperand(0).getReg();
Register OrigOp = MI.getOperand(1).getReg();
@@ -233,7 +233,14 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
return false;
MachineInstr *OrigDef = MRI.getUniqueVRegDef(OrigOp);
- // Avoid trying to fold G_PHI and G_UNMERGE_VALUES.
+ // Even if only a single operand of the PHI is not guaranteed non-poison,
+ // moving freeze() backwards across a PHI can cause optimization issues for
+ // other users of that operand.
+ //
+ // Moving freeze() from one of the output registers of a G_UNMERGE_VALUES to
+ // the source register is unprofitable because it makes the freeze() more
+ // strict than is necessary (it would affect the whole register instead of
+ // just the subreg being frozen).
if (OrigDef->isPHI() || isa<GUnmerge>(OrigDef))
return false;
@@ -243,7 +250,6 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
std::optional<MachineOperand> MaybePoisonOperand;
for (MachineOperand &Operand : OrigDef->uses()) {
- // Avoid working on non-register operands.
if (!Operand.isReg())
return false;
>From fffbc9fa2a223c63b204f44e41993c13897e73d9 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Fri, 17 May 2024 07:54:55 +0530
Subject: [PATCH 7/9] Fix silly mistake
---
llvm/lib/Target/AArch64/AArch64Combine.td | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Target/AArch64/AArch64Combine.td b/llvm/lib/Target/AArch64/AArch64Combine.td
index 7229d4fe52261..1c7f6b870d390 100644
--- a/llvm/lib/Target/AArch64/AArch64Combine.td
+++ b/llvm/lib/Target/AArch64/AArch64Combine.td
@@ -296,5 +296,5 @@ def AArch64PostLegalizerCombiner
split_store_zero_128, undef_combines,
select_to_minmax, or_to_bsp, combine_concat_vector,
commute_constant_to_rhs,
- push_freeze_to_prevent_poison_propagation]> {
+ push_freeze_to_prevent_poison_from_propagating]> {
}
>From 6fcc9f66581be3d4f48a86c6a8f267f3cd66ca06 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Mon, 20 May 2024 16:44:08 +0530
Subject: [PATCH 8/9] Rebase and address reviewer comments
---
llvm/lib/CodeGen/GlobalISel/Utils.cpp | 26 +++++++++++---------------
1 file changed, 11 insertions(+), 15 deletions(-)
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index 741363e1d7733..f455482e02943 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -1771,26 +1771,22 @@ static bool isGuaranteedNotToBeUndefOrPoison(Register Reg,
MachineInstr *RegDef = MRI.getVRegDef(Reg);
- auto OpCheck = [&](MachineOperand &Operand) {
- if (!Operand.isReg())
- return true;
-
- return isGuaranteedNotToBeUndefOrPoison(Operand.getReg(), MRI, Depth + 1,
- Kind);
- };
-
switch (RegDef->getOpcode()) {
case TargetOpcode::G_FREEZE:
return true;
case TargetOpcode::G_IMPLICIT_DEF:
return !includesUndef(Kind);
- default:
- GenericMachineInstr *Opr = dyn_cast<GBinOp>(RegDef);
- if (!Opr)
- Opr = dyn_cast<GCastOp>(RegDef);
-
- return Opr && !::llvm::canCreateUndefOrPoison(Reg, MRI) &&
- all_of(Opr->operands(), OpCheck);
+ default: {
+ auto MOCheck = [&](const MachineOperand &MO) {
+ if (!MO.isReg())
+ return true;
+ return ::isGuaranteedNotToBeUndefOrPoison(MO.getReg(), MRI, Depth + 1,
+ Kind);
+ };
+ return !::canCreateUndefOrPoison(Reg, MRI,
+ /*ConsiderFlagsAndMetadata=*/true, Kind) &&
+ all_of(RegDef->uses(), MOCheck);
+ }
}
}
>From 4291abda4ba74e45fe5ffdaf3f23fca31763abe5 Mon Sep 17 00:00:00 2001
From: Dhruv Chawla <dhruvc at nvidia.com>
Date: Tue, 21 May 2024 15:08:04 +0530
Subject: [PATCH 9/9] Create clearFlags()
---
.../llvm/CodeGen/GlobalISel/GenericMachineInstrs.h | 9 ++-------
llvm/include/llvm/CodeGen/MachineInstr.h | 6 ++++++
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
index f3c729900f13d..2b3efc3b609f0 100644
--- a/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
+++ b/llvm/include/llvm/CodeGen/GlobalISel/GenericMachineInstrs.h
@@ -41,13 +41,8 @@ class GenericMachineInstr : public MachineInstr {
}
void dropPoisonGeneratingFlags() {
- clearFlag(NoUWrap);
- clearFlag(NoSWrap);
- clearFlag(IsExact);
- clearFlag(Disjoint);
- clearFlag(NonNeg);
- clearFlag(FmNoNans);
- clearFlag(FmNoInfs);
+ clearFlags(NoUWrap | NoSWrap | IsExact | Disjoint | NonNeg | FmNoNans |
+ FmNoInfs);
assert(!hasPoisonGeneratingFlags());
}
};
diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h
index 2b0c5d166d88b..db48a0ae55145 100644
--- a/llvm/include/llvm/CodeGen/MachineInstr.h
+++ b/llvm/include/llvm/CodeGen/MachineInstr.h
@@ -416,6 +416,12 @@ class MachineInstr
Flags &= ~((uint32_t)Flag);
}
+ void clearFlags(unsigned flags) {
+ assert(isUInt<LLVM_MI_FLAGS_BITS>(flags) &&
+ "flags to be cleared are out of range for the Flags field");
+ Flags &= ~flags;
+ }
+
/// Return true if MI is in a bundle (but not the first MI in a bundle).
///
/// A bundle looks like this before it's finalized:
More information about the llvm-commits
mailing list