[llvm] bbaa04b - [GlobalISel][AArch64] Tweak `G_FREEZE` legalization, don't push it when that makes code illegal (#204785)

via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 29 01:02:06 PDT 2026


Author: Ömer Sinan Ağacan
Date: 2026-06-29T09:02:01+01:00
New Revision: bbaa04b4ba4c9a6049e0618e97d7d1db85a8a06c

URL: https://github.com/llvm/llvm-project/commit/bbaa04b4ba4c9a6049e0618e97d7d1db85a8a06c
DIFF: https://github.com/llvm/llvm-project/commit/bbaa04b4ba4c9a6049e0618e97d7d1db85a8a06c.diff

LOG: [GlobalISel][AArch64] Tweak `G_FREEZE` legalization, don't push it when that makes code illegal (#204785)

In the combine rule

    // Convert freeze(Op(Op0, NonPoisonOps...)) to Op(freeze(Op0), NonPoisonOps...)
    // when Op0 is not guaranteed non-poison
    def push_freeze_to_prevent_poison_from_propagating ...

Don't push the `freeze` if `freeze(Op0)` is illegal and we've already
run the legalizer.

Also make `G_FREEZE`, `G_IMPLICIT_DEF`, `G_CONSTANT_FOLD_BARRIER` legal for
`s128` operands.

Two new tests added:

- `free-push-legal.mir` checks that we don't push `freeze` towards operands
  post-legalization when doing so makes the code illegal.

  We use an instruction here that's unlikely to be made legal for `G_FREEZE`
  (variable sized vector load).

- `freeze-push-legal.mir` checks the opposite on `s128` values.

Fixes the crashes like:

    LLVM ERROR: instruction is not legal: %8:_(i128) = G_FREEZE %0:_ (in function: _0)

Added: 
    llvm/test/CodeGen/AArch64/GlobalISel/freeze-push.mir

Modified: 
    llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
    llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
    llvm/test/CodeGen/AArch64/GlobalISel/legalize-undef.mir

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
index b4809c95f872c..ab0003cab6c2a 100644
--- a/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CombinerHelper.cpp
@@ -252,6 +252,8 @@ void CombinerHelper::applyCombineCopy(MachineInstr &MI) const {
 
 bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
     MachineInstr &MI, BuildFnTy &MatchInfo) const {
+  assert(MI.getOpcode() == TargetOpcode::G_FREEZE && "Invalid instruction");
+
   // Ported from InstCombinerImpl::pushFreezeToPreventPoisonFromPropagating.
   Register DstOp = MI.getOperand(0).getReg();
   Register OrigOp = MI.getOperand(1).getReg();
@@ -306,6 +308,10 @@ bool CombinerHelper::matchFreezeOfSingleMaybePoisonOperand(
   Register MaybePoisonOperandReg = MaybePoisonOperand->getReg();
   LLT MaybePoisonOperandRegTy = MRI.getType(MaybePoisonOperandReg);
 
+  if (!isLegalOrBeforeLegalizer(
+          {TargetOpcode::G_FREEZE, {MaybePoisonOperandRegTy}}))
+    return false;
+
   MatchInfo = [=](MachineIRBuilder &B) mutable {
     Observer.changingInstr(*OrigDef);
     cast<GenericMachineInstr>(OrigDef)->dropPoisonGeneratingFlags();

diff  --git a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
index e6521a211226e..6eb8d87082055 100644
--- a/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
+++ b/llvm/lib/Target/AArch64/GISel/AArch64LegalizerInfo.cpp
@@ -133,7 +133,7 @@ AArch64LegalizerInfo::AArch64LegalizerInfo(const AArch64Subtarget &ST)
 
   getActionDefinitionsBuilder(
       {G_IMPLICIT_DEF, G_FREEZE, G_CONSTANT_FOLD_BARRIER})
-      .legalFor({p0, s8, s16, s32, s64})
+      .legalFor({p0, s8, s16, s32, s64, s128})
       .legalFor({v2s8, v4s8, v8s8, v16s8, v2s16, v4s16, v8s16, v2s32, v4s32,
                  v2s64, v2p0})
       .widenScalarToNextPow2(0)

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/freeze-push.mir b/llvm/test/CodeGen/AArch64/GlobalISel/freeze-push.mir
new file mode 100644
index 0000000000000..37db93b881730
--- /dev/null
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/freeze-push.mir
@@ -0,0 +1,50 @@
+# NOTE: Assertions have been autogenerated by utils/update_mir_test_checks.py
+# RUN: llc -mtriple=arm64-apple-macosx -run-pass=aarch64-postlegalizer-combiner %s -o - | FileCheck %s
+---
+name:            freeze_push_legal
+legalized:       true
+body:             |
+  bb.0.entry:
+    liveins: $x0
+    ; CHECK-LABEL: name: freeze_push_legal
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(i128) = G_LOAD [[COPY]](p0) :: (load (i128))
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(i128) = G_FREEZE [[LOAD]]
+    ; CHECK-NEXT: [[TRUNC:%[0-9]+]]:_(i64) = G_TRUNC [[FREEZE]](i128)
+    ; CHECK-NEXT: [[TRUNC1:%[0-9]+]]:_(i32) = G_TRUNC [[TRUNC]](i64)
+    ; CHECK-NEXT: $w0 = COPY [[TRUNC1]](i32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %0:_(p0) = COPY $x0
+    %1:_(i128) = G_LOAD %0(p0) :: (load (i128))
+    %4:_(i64), %5:_(i64) = G_UNMERGE_VALUES %1(i128)
+    %6:_(i64) = G_FREEZE %4
+    %3:_(i32) = G_TRUNC %6(i64)
+    $w0 = COPY %3(i32)
+    RET_ReallyLR implicit $w0
+...
+---
+name:            freeze_push_illegal
+legalized:       true
+body:             |
+  bb.0.entry:
+    liveins: $x0
+    ; CHECK-LABEL: name: freeze_push_illegal
+    ; CHECK: liveins: $x0
+    ; CHECK-NEXT: {{  $}}
+    ; CHECK-NEXT: [[COPY:%[0-9]+]]:_(p0) = COPY $x0
+    ; CHECK-NEXT: [[LOAD:%[0-9]+]]:_(<vscale x 4 x s32>) = G_LOAD [[COPY]](p0) :: (load (<vscale x 4 x s32>))
+    ; CHECK-NEXT: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 0
+    ; CHECK-NEXT: [[EVEC:%[0-9]+]]:_(s32) = G_EXTRACT_VECTOR_ELT [[LOAD]](<vscale x 4 x s32>), [[C]](s64)
+    ; CHECK-NEXT: [[FREEZE:%[0-9]+]]:_(s32) = G_FREEZE [[EVEC]]
+    ; CHECK-NEXT: $w0 = COPY [[FREEZE]](s32)
+    ; CHECK-NEXT: RET_ReallyLR implicit $w0
+    %0:_(p0) = COPY $x0
+    %1:_(<vscale x 4 x s32>) = G_LOAD %0(p0) :: (load (<vscale x 4 x s32>))
+    %2:_(s64) = G_CONSTANT i64 0
+    %3:_(s32) = G_EXTRACT_VECTOR_ELT %1, %2
+    %4:_(s32) = G_FREEZE %3
+    $w0 = COPY %4(s32)
+    RET_ReallyLR implicit $w0
+...

diff  --git a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-undef.mir b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-undef.mir
index 9726cc59ed06f..72196862cfbd4 100644
--- a/llvm/test/CodeGen/AArch64/GlobalISel/legalize-undef.mir
+++ b/llvm/test/CodeGen/AArch64/GlobalISel/legalize-undef.mir
@@ -9,8 +9,8 @@ body: |
     ; CHECK-LABEL: name: test_implicit_def
     ; CHECK: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
     ; CHECK-NEXT: $x0 = COPY [[DEF]](s64)
-    %0:_(s128) = G_IMPLICIT_DEF
-    %1:_(s64) = G_TRUNC %0(s128)
+    %0:_(s256) = G_IMPLICIT_DEF
+    %1:_(s64) = G_TRUNC %0(s256)
     $x0 = COPY %1(s64)
 ...
 
@@ -104,6 +104,6 @@ body: |
     ; CHECK-LABEL: name: test_implicit_def_s88
     ; CHECK: [[DEF:%[0-9]+]]:_(s64) = G_IMPLICIT_DEF
     ; CHECK-NEXT: $x0 = COPY [[DEF]](s64)
-    %undef:_(s88) = G_IMPLICIT_DEF
+    %undef:_(s130) = G_IMPLICIT_DEF
     %trunc:_(s64) = G_TRUNC %undef
     $x0 = COPY %trunc(s64)


        


More information about the llvm-commits mailing list