[llvm] [GlobalIsel] Combine freeze (PR #93239)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 23 14:14:55 PDT 2024
Thorsten =?utf-8?q?Schütt?= <schuett at gmail.com>,
Thorsten =?utf-8?q?Schütt?= <schuett at gmail.com>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/93239 at github.com>
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-aarch64
@llvm/pr-subscribers-backend-amdgpu
Author: Thorsten Schütt (tschuett)
<details>
<summary>Changes</summary>
---
Patch is 87.97 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/93239.diff
9 Files Affected:
- (modified) llvm/include/llvm/Target/GlobalISel/Combine.td (+14-4)
- (modified) llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp (+3-2)
- (modified) llvm/lib/CodeGen/GlobalISel/Utils.cpp (+92-10)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-extract-vec-elt.mir (+2-2)
- (added) llvm/test/CodeGen/AArch64/GlobalISel/combine-freeze.mir (+610)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/combine-insert-vec-elt.mir (+3-3)
- (modified) llvm/test/CodeGen/AArch64/GlobalISel/prelegalizer-combiner-divrem-insertpt-crash.mir (+1-2)
- (modified) llvm/test/CodeGen/AArch64/fast-isel-select.ll (+343-111)
- (modified) llvm/test/CodeGen/AMDGPU/div_i128.ll (+216-274)
``````````diff
diff --git a/llvm/include/llvm/Target/GlobalISel/Combine.td b/llvm/include/llvm/Target/GlobalISel/Combine.td
index 8012f91922777..47f73daf20891 100644
--- a/llvm/include/llvm/Target/GlobalISel/Combine.td
+++ b/llvm/include/llvm/Target/GlobalISel/Combine.td
@@ -1636,7 +1636,7 @@ extract_vector_element_build_vector_trunc5,
extract_vector_element_build_vector_trunc6,
extract_vector_element_build_vector_trunc7,
extract_vector_element_build_vector_trunc8,
-extract_vector_element_freeze,
+//extract_vector_element_freeze,
extract_vector_element_shuffle_vector,
insert_vector_element_extract_vector_element
]>;
@@ -1713,6 +1713,17 @@ def integer_reassoc_combines: GICombineGroup<[
APlusBMinusCPlusA
]>;
+def freeze_of_not_undef_and_poison : GICombineRule<
+ (defs root:$root),
+ (match (G_FREEZE $root, $src),
+ [{ return isGuaranteedNotToBeUndefOrPoison(${src}.getReg(), MRI); }]),
+ (apply (GIReplaceReg $root, $src))>;
+
+def freeze_combines: GICombineGroup<[
+ freeze_of_not_undef_and_poison,
+ push_freeze_to_prevent_poison_from_propagating
+]>;
+
// FIXME: These should use the custom predicate feature once it lands.
def undef_combines : GICombineGroup<[undef_to_fp_zero, undef_to_int_zero,
undef_to_negative_one,
@@ -1771,7 +1782,7 @@ def constant_fold_binops : GICombineGroup<[constant_fold_binop,
constant_fold_fp_binop]>;
def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_combines,
- vector_ops_combines,
+ vector_ops_combines, freeze_combines,
insert_vec_elt_combines, extract_vec_elt_combines, combines_for_extload,
combine_extracted_vector_load,
undef_combines, identity_combines, phi_combines,
@@ -1793,8 +1804,7 @@ def all_combines : GICombineGroup<[integer_reassoc_combines, trivial_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,
- push_freeze_to_prevent_poison_from_propagating]>;
+ sext_trunc, zext_trunc, combine_shuffle_concat]>;
// 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 4cc602b5c8709..abecee4259030 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -265,11 +265,12 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
}
}
- cast<GenericMachineInstr>(OrigDef)->dropPoisonGeneratingFlags();
+ // FIXME: observer must be aware of dropping
+ // cast<GenericMachineInstr>(OrigDef)->dropPoisonGeneratingFlags();
// Eliminate freeze if all operands are guaranteed non-poison.
if (!MaybePoisonOperand) {
- MatchInfo = [=](MachineIRBuilder &B) { MRI.replaceRegWith(DstOp, OrigOp); };
+ MatchInfo = [=](MachineIRBuilder &B) { B.buildCopy(DstOp, OrigOp); };
return true;
}
diff --git a/llvm/lib/CodeGen/GlobalISel/Utils.cpp b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
index f455482e02943..e8438be94b3cd 100644
--- a/llvm/lib/CodeGen/GlobalISel/Utils.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/Utils.cpp
@@ -1724,6 +1724,39 @@ bool llvm::isPreISelGenericFloatingPointOpcode(unsigned Opc) {
}
}
+/// Shifts return poison if shiftwidth is larger than the bitwidth.
+static bool shiftAmountKnownInRange(Register ShiftAmount,
+ const MachineRegisterInfo &MRI) {
+ LLT Ty = MRI.getType(ShiftAmount);
+
+ if (Ty.isScalableVector())
+ return false; // Can't tell, just return false to be safe
+
+ if (Ty.isScalar()) {
+ std::optional<ValueAndVReg> Val =
+ getIConstantVRegValWithLookThrough(ShiftAmount, MRI);
+ if (!Val)
+ return false;
+ return Val->Value.ult(Ty.getScalarSizeInBits());
+ }
+
+ GBuildVector *BV = getOpcodeDef<GBuildVector>(ShiftAmount, MRI);
+ if (!BV)
+ return false;
+
+ unsigned Sources = BV->getNumSources();
+ for (unsigned I = 0; I < Sources; ++I) {
+ std::optional<ValueAndVReg> Val =
+ getIConstantVRegValWithLookThrough(BV->getSourceReg(I), MRI);
+ if (!Val)
+ return false;
+ if (!Val->Value.ult(Ty.getScalarSizeInBits()))
+ return false;
+ }
+
+ return true;
+}
+
namespace {
enum class UndefPoisonKind {
PoisonOnly = (1 << 0),
@@ -1732,11 +1765,11 @@ enum class UndefPoisonKind {
};
}
-[[maybe_unused]] static bool includesPoison(UndefPoisonKind Kind) {
+static bool includesPoison(UndefPoisonKind Kind) {
return (unsigned(Kind) & unsigned(UndefPoisonKind::PoisonOnly)) != 0;
}
-[[maybe_unused]] static bool includesUndef(UndefPoisonKind Kind) {
+static bool includesUndef(UndefPoisonKind Kind) {
return (unsigned(Kind) & unsigned(UndefPoisonKind::UndefOnly)) != 0;
}
@@ -1745,18 +1778,55 @@ 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;
- } else {
- // Conservatively return true.
- return true;
- }
+ if (ConsiderFlagsAndMetadata && includesPoison(Kind))
+ if (auto *GMI = dyn_cast<GenericMachineInstr>(RegDef))
+ if (GMI->hasPoisonGeneratingFlags())
+ return true;
+ // Check whether opcode is a poison/undef-generating operation.
switch (RegDef->getOpcode()) {
case TargetOpcode::G_FREEZE:
+ case TargetOpcode::G_BUILD_VECTOR:
+ case TargetOpcode::G_CONSTANT_FOLD_BARRIER:
return false;
+ case TargetOpcode::G_SHL:
+ case TargetOpcode::G_ASHR:
+ case TargetOpcode::G_LSHR:
+ return includesPoison(Kind) &&
+ !shiftAmountKnownInRange(RegDef->getOperand(2).getReg(), MRI);
+ case TargetOpcode::G_FPTOSI:
+ case TargetOpcode::G_FPTOUI:
+ // fptosi/ui yields poison if the resulting value does not fit in the
+ // destination type.
+ return true;
+ case TargetOpcode::G_CTLZ:
+ case TargetOpcode::G_CTTZ:
+ case TargetOpcode::G_ABS:
+ case TargetOpcode::G_CTPOP:
+ case TargetOpcode::G_BSWAP:
+ case TargetOpcode::G_BITREVERSE:
+ case TargetOpcode::G_FSHL:
+ case TargetOpcode::G_FSHR:
+ case TargetOpcode::G_SMAX:
+ case TargetOpcode::G_SMIN:
+ case TargetOpcode::G_UMAX:
+ case TargetOpcode::G_UMIN:
+ case TargetOpcode::G_PTRMASK:
+ case TargetOpcode::G_SADDO:
+ case TargetOpcode::G_SSUBO:
+ case TargetOpcode::G_UADDO:
+ case TargetOpcode::G_USUBO:
+ case TargetOpcode::G_SMULO:
+ case TargetOpcode::G_UMULO:
+ case TargetOpcode::G_SADDSAT:
+ case TargetOpcode::G_UADDSAT:
+ case TargetOpcode::G_SSUBSAT:
+ case TargetOpcode::G_USUBSAT:
+ return false;
+ case TargetOpcode::G_SSHLSAT:
+ case TargetOpcode::G_USHLSAT:
+ return includesPoison(Kind) &&
+ !shiftAmountKnownInRange(RegDef->getOperand(2).getReg(), MRI);
default:
return !isa<GCastOp>(RegDef) && !isa<GBinOp>(RegDef);
}
@@ -1776,6 +1846,18 @@ static bool isGuaranteedNotToBeUndefOrPoison(Register Reg,
return true;
case TargetOpcode::G_IMPLICIT_DEF:
return !includesUndef(Kind);
+ case TargetOpcode::G_CONSTANT:
+ case TargetOpcode::G_FCONSTANT:
+ return true;
+ case TargetOpcode::G_BUILD_VECTOR: {
+ GBuildVector *BV = cast<GBuildVector>(RegDef);
+ unsigned NumSources = BV->getNumSources();
+ for (unsigned I = 0; I < NumSources; ++I)
+ if (!::isGuaranteedNotToBeUndefOrPoison(BV->getSourceReg(I), MRI,
+ Depth + 1, Kind))
+ return false;
+ return true;
+ }
default: {
auto MOCheck = [&](const MachineOperand &MO) {
if (!MO.isReg())
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-extract-vec-elt.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-extract-vec-elt.mir
index d5d33742148ad..70241e71aa593 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/combine-extract-vec-elt.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-extract-vec-elt.mir
@@ -361,8 +361,8 @@ body: |
; CHECK-NEXT: {{ $}}
; CHECK-NEXT: %vec:_(<2 x s64>) = COPY $q0
; CHECK-NEXT: %idx:_(s64) = COPY $x1
- ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s64) = G_EXTRACT_VECTOR_ELT %vec(<2 x s64>), %idx(s64)
- ; CHECK-NEXT: %extract:_(s64) = G_FREEZE [[EVEC]]
+ ; CHECK-NEXT: %fvec:_(<2 x s64>) = G_FREEZE %vec
+ ; CHECK-NEXT: %extract:_(s64) = G_EXTRACT_VECTOR_ELT %fvec(<2 x s64>), %idx(s64)
; CHECK-NEXT: $x0 = COPY %extract(s64)
; CHECK-NEXT: RET_ReallyLR implicit $x0
%vec:_(<2 x s64>) = COPY $q0
diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/combine-freeze.mir b/llvm/test/CodeGen/AArch64/GlobalISel/combine-freeze.mir
new file mode 100644
index 0000000000000..dfa45d96fe94c
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/combine-freeze.mir
@@ -0,0 +1,610 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -o - -mtriple=aarch64-unknown-unknown -run-pass=aarch64-prelegalizer-combiner -verify-machineinstrs %s | FileCheck %s
+
+...
+---
+name: freeze_register
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_register
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY]]
+ ; CHECK-NEXT: $x0 = COPY [[FREEZE]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %2:_(s64) = G_FREEZE %0
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: freeze_constant
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_constant
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_CONSTANT i64 9
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+
+...
+---
+name: freeze_fconstant
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_fconstant
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_FCONSTANT double 9.000000e+00
+ ; CHECK-NEXT: $x0 = COPY [[C]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FCONSTANT double 9.0
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_undef
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_undef
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[DEF]]
+ ; CHECK-NEXT: $x0 = COPY [[FREEZE]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_IMPLICIT_DEF
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_freeze
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_freeze
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s64) = COPY $x0
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s64) = G_FREEZE [[COPY]]
+ ; CHECK-NEXT: $x0 = COPY [[FREEZE]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %1:_(s64) = G_FREEZE %0
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_buildvector
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_buildvector
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(s32) = COPY $w0
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR [[COPY]](s32), [[COPY]](s32), [[COPY]](s32), [[COPY]](s32)
+ ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(<4 x s32>) = G_FREEZE [[BUILD_VECTOR]]
+ ; CHECK-NEXT: $q0 = COPY [[FREEZE]](<4 x s32>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
+ %0:_(s32) = COPY $w0
+ %1:_(<4 x s32>) = G_BUILD_VECTOR %0(s32), %0(s32), %0(s32), %0(s32)
+ %2:_(<4 x s32>) = G_FREEZE %1
+ $q0 = COPY %2(<4 x s32>)
+ RET_ReallyLR implicit $q0
+...
+---
+name: freeze_buildvector_const
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_buildvector_const
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %c:_(s32) = G_CONSTANT i32 6
+ ; CHECK-NEXT: [[BUILD_VECTOR:%[0-9]+]]:_(<4 x s32>) = G_BUILD_VECTOR %c(s32), %c(s32), %c(s32), %c(s32)
+ ; CHECK-NEXT: $q0 = COPY [[BUILD_VECTOR]](<4 x s32>)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
+ %0:_(s32) = COPY $w0
+ %c:_(s32) = G_CONSTANT i32 6
+ %1:_(<4 x s32>) = G_BUILD_VECTOR %c(s32), %c(s32), %c(s32), %c(s32)
+ %2:_(<4 x s32>) = G_FREEZE %1
+ $q0 = COPY %2(<4 x s32>)
+ RET_ReallyLR implicit $q0
+...
+---
+name: freeze_disjoint_or_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_disjoint_or_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: $x0 = COPY %c(s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %cst:_(s64) = G_CONSTANT i64 9
+ %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s64) = disjoint G_OR %c, %c
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_or_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_or_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: $x0 = COPY %c(s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %cst:_(s64) = G_CONSTANT i64 9
+ %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s64) = G_OR %c, %c
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_nneg_zext_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_nneg_zext_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 9
+ ; CHECK-NEXT: %c:_(s32) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: %3:_(s64) = nneg G_ZEXT %c(s32)
+ ; CHECK-NEXT: $x0 = COPY %3(s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %cst:_(s32) = G_CONSTANT i32 9
+ %c:_(s32) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s64) = nneg G_ZEXT %c
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_zext_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_zext_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s32) = G_CONSTANT i32 9
+ ; CHECK-NEXT: %c:_(s32) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: [[ZEXT:%[0-9]+]]:_(s64) = G_ZEXT %c(s32)
+ ; CHECK-NEXT: $x0 = COPY [[ZEXT]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %cst:_(s32) = G_CONSTANT i32 9
+ %c:_(s32) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s64) = G_ZEXT %c
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_udiv_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_udiv_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: [[UDIV:%[0-9]+]]:_(s64) = G_UDIV %c, %c
+ ; CHECK-NEXT: $x0 = COPY [[UDIV]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %cst:_(s64) = G_CONSTANT i64 9
+ %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s64) = G_UDIV %c, %c
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_exact_udiv_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_exact_udiv_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: [[UDIV:%[0-9]+]]:_(s64) = exact G_UDIV %c, %c
+ ; CHECK-NEXT: $x0 = COPY [[UDIV]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %cst:_(s64) = G_CONSTANT i64 9
+ %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s64) = exact G_UDIV %c, %c
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_mul_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_mul_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = G_MUL %c, %c
+ ; CHECK-NEXT: $x0 = COPY [[MUL]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %cst:_(s64) = G_CONSTANT i64 9
+ %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s64) = G_MUL %c, %c
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_nsw_mul_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_nsw_mul_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: [[MUL:%[0-9]+]]:_(s64) = nsw G_MUL %c, %c
+ ; CHECK-NEXT: $x0 = COPY [[MUL]](s64)
+ ; CHECK-NEXT: RET_ReallyLR implicit $x0
+ %0:_(s64) = COPY $x0
+ %cst:_(s64) = G_CONSTANT i64 9
+ %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s64) = nsw G_MUL %c, %c
+ %2:_(s64) = G_FREEZE %1
+ $x0 = COPY %2(s64)
+ RET_ReallyLR implicit $x0
+...
+---
+name: freeze_trunc_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_trunc_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = G_TRUNC %c(s64)
+ ; CHECK-NEXT: $w0 = COPY [[TRUNC]](s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
+ %0:_(s64) = COPY $x0
+ %cst:_(s64) = G_CONSTANT i64 9
+ %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s32) = G_TRUNC %c
+ %2:_(s32) = G_FREEZE %1
+ $w0 = COPY %2(s32)
+ RET_ReallyLR implicit $q0
+...
+---
+name: freeze_nuw_trunc_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_nuw_trunc_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEXT: %cst:_(s64) = G_CONSTANT i64 9
+ ; CHECK-NEXT: %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(s32) = nuw G_TRUNC %c(s64)
+ ; CHECK-NEXT: $w0 = COPY [[TRUNC]](s32)
+ ; CHECK-NEXT: RET_ReallyLR implicit $q0
+ %0:_(s64) = COPY $x0
+ %cst:_(s64) = G_CONSTANT i64 9
+ %c:_(s64) = G_CONSTANT_FOLD_BARRIER %cst
+ %1:_(s32) = nuw G_TRUNC %c
+ %2:_(s32) = G_FREEZE %1
+ $w0 = COPY %2(s32)
+ RET_ReallyLR implicit $q0
+...
+---
+name: freeze_add_fold_barrier
+body: |
+ bb.1:
+ liveins: $w0
+
+ ; CHECK-LABEL: name: freeze_add_fold_barrier
+ ; CHECK: liveins: $w0
+ ; CHECK-NEXT: {{ $}}
+ ; CHECK-NEX...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/93239
More information about the llvm-commits
mailing list