[llvm] [SelectionDAG] Fix dangling SUnit node after unfold during scheduling (PR #202295)
Paweł Bylica via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 14 03:27:28 PDT 2026
https://github.com/chfast updated https://github.com/llvm/llvm-project/pull/202295
>From 3fa62cd19ab11585e67cada4b56b40aadef75614 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Bylica?= <pawel at hepcolgum.band>
Date: Mon, 8 Jun 2026 10:39:43 +0200
Subject: [PATCH 1/2] [SelectionDAG] Fix dangling SUnit node after unfold
during scheduling
When a scheduler unfolds a load (TryUnfoldSU), it replaces all uses of the
folded node. A replacement can recursively CSE-merge a user into an existing
equivalent node and delete it; if that deleted node was owned by an SUnit, the
SUnit was left with a dangling SDNode pointer, later causing a use-after-free
and "Node emitted out of order - early" in InstrEmitter.
Register a DAGNodeDeletedListener around the replacements that redirects the
affected SUnit to the surviving node, shared via a RedirectMergedNode helper
on the common base. Apply the same fix to the fast scheduler.
Fixes #63309.
Fixes #63312.
Fixes #120631.
---
.../CodeGen/SelectionDAG/ScheduleDAGFast.cpp | 5 ++
.../SelectionDAG/ScheduleDAGRRList.cpp | 7 +-
.../SelectionDAG/ScheduleDAGSDNodes.cpp | 10 +++
.../CodeGen/SelectionDAG/ScheduleDAGSDNodes.h | 5 ++
llvm/test/CodeGen/X86/pr63309.ll | 85 +++++++++++++++++++
5 files changed, 111 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/X86/pr63309.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
index 0f67cee757407..817814b5b1b86 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
@@ -232,6 +232,11 @@ SUnit *ScheduleDAGFast::CopyAndMoveSuccessors(SUnit *SU) {
SDNode *LoadNode = NewNodes[0];
unsigned NumVals = N->getNumValues();
unsigned OldNumVals = SU->getNode()->getNumValues();
+ // Fix up SUnits whose nodes get deleted by the replacements below.
+ SelectionDAG::DAGNodeDeletedListener Listener(
+ *DAG, [&](SDNode *DeadNode, SDNode *NewNode) {
+ RedirectMergedNode(DeadNode, NewNode);
+ });
for (unsigned i = 0; i != NumVals; ++i)
DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), i), SDValue(N, i));
DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), OldNumVals-1),
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index fffe5b8a83501..b6b74f623e98d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1045,7 +1045,12 @@ SUnit *ScheduleDAGRRList::TryUnfoldSU(SUnit *SU) {
LLVM_DEBUG(dbgs() << "Unfolding SU #" << SU->NodeNum << "\n");
- // Now that we are committed to unfolding replace DAG Uses.
+ // Now that we are committed to unfolding replace DAG Uses, fixing up SUnits
+ // whose nodes get deleted by the replacements.
+ SelectionDAG::DAGNodeDeletedListener Listener(
+ *DAG, [&](SDNode *DeadNode, SDNode *NewNode) {
+ RedirectMergedNode(DeadNode, NewNode);
+ });
for (unsigned i = 0; i != NumVals; ++i)
DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), i), SDValue(N, i));
DAG->ReplaceAllUsesOfValueWith(SDValue(SU->getNode(), OldNumVals - 1),
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index 58101f415ce51..39429e30edf1b 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -105,6 +105,16 @@ SUnit *ScheduleDAGSDNodes::Clone(SUnit *Old) {
return SU;
}
+void ScheduleDAGSDNodes::RedirectMergedNode(SDNode *DeadNode, SDNode *NewNode) {
+ int Id = DeadNode->getNodeId();
+ if (Id == -1 || unsigned(Id) >= SUnits.size() ||
+ SUnits[Id].getNode() != DeadNode)
+ return;
+ SUnits[Id].setNode(NewNode);
+ if (NewNode->getNodeId() == -1)
+ NewNode->setNodeId(Id);
+}
+
/// CheckForPhysRegDependency - Check if the dependency between def and use of
/// a specified operand is a physical register dependency. If so, returns the
/// register and the cost of copying the register.
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
index ff5615b7658f3..e6551f6ab186d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.h
@@ -90,6 +90,11 @@ class InstrItineraryData;
///
SUnit *Clone(SUnit *Old);
+ /// If an SUnit owns \p DeadNode, which is being deleted and replaced by
+ /// \p NewNode (e.g. when a node is CSE'd into an existing one), point that
+ /// SUnit at \p NewNode so it is not left with a dangling node pointer.
+ void RedirectMergedNode(SDNode *DeadNode, SDNode *NewNode);
+
/// BuildSchedGraph - Build the SUnit graph from the selection dag that we
/// are input. This SUnit graph is similar to the SelectionDAG, but
/// excludes nodes that aren't interesting to scheduling, and represents
diff --git a/llvm/test/CodeGen/X86/pr63309.ll b/llvm/test/CodeGen/X86/pr63309.ll
new file mode 100644
index 0000000000000..4a89cb090fdc5
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr63309.ll
@@ -0,0 +1,85 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=RRLIST
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -pre-RA-sched=fast | FileCheck %s --check-prefix=FAST
+
+; Make sure this does not crash with "Node emitted out of order - early".
+; Unfolding a load during scheduling replaces all uses of the folded node,
+; which can CSE-merge and delete a node still referenced by another SUnit.
+; Both the list (ScheduleDAGRRList) and fast (ScheduleDAGFast) schedulers
+; perform this unfold, so exercise both.
+
+ at G.1 = external global i1
+ at G.5 = external global ptr
+
+define void @pr63309(ptr %G.5, i64 %L3) {
+; RRLIST-LABEL: pr63309:
+; RRLIST: # %bb.0: # %BB
+; RRLIST-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax
+; RRLIST-NEXT: andl $1, %eax
+; RRLIST-NEXT: negq %rax
+; RRLIST-NEXT: movb $0, -{{[0-9]+}}(%rsp)
+; RRLIST-NEXT: movzbl (%rax), %eax
+; RRLIST-NEXT: movq G.1 at GOTPCREL(%rip), %rcx
+; RRLIST-NEXT: movq 0, %rdx
+; RRLIST-NEXT: movb $0, (%rcx)
+; RRLIST-NEXT: movq $0, -{{[0-9]+}}(%rsp)
+; RRLIST-NEXT: movq G.5 at GOTPCREL(%rip), %rcx
+; RRLIST-NEXT: movq $0, (%rcx)
+; RRLIST-NEXT: testq %rsi, %rsi
+; RRLIST-NEXT: setg 0
+; RRLIST-NEXT: testq %rdx, %rdx
+; RRLIST-NEXT: movq $0, (%rdi)
+; RRLIST-NEXT: movb %al, 0
+; RRLIST-NEXT: setne (%rdi)
+; RRLIST-NEXT: testb %al, %al
+; RRLIST-NEXT: sets 0
+; RRLIST-NEXT: retq
+;
+; FAST-LABEL: pr63309:
+; FAST: # %bb.0: # %BB
+; FAST-NEXT: movq G.1 at GOTPCREL(%rip), %rax
+; FAST-NEXT: movzbl -{{[0-9]+}}(%rsp), %ecx
+; FAST-NEXT: andl $1, %ecx
+; FAST-NEXT: negq %rcx
+; FAST-NEXT: movb $0, -{{[0-9]+}}(%rsp)
+; FAST-NEXT: movzbl (%rcx), %ecx
+; FAST-NEXT: movq 0, %rdx
+; FAST-NEXT: movb $0, (%rax)
+; FAST-NEXT: movq G.5 at GOTPCREL(%rip), %rax
+; FAST-NEXT: movq $0, (%rax)
+; FAST-NEXT: movq $0, -{{[0-9]+}}(%rsp)
+; FAST-NEXT: testq %rsi, %rsi
+; FAST-NEXT: setg 0
+; FAST-NEXT: testq %rdx, %rdx
+; FAST-NEXT: movq $0, (%rdi)
+; FAST-NEXT: movb %cl, 0
+; FAST-NEXT: setne (%rdi)
+; FAST-NEXT: testb %cl, %cl
+; FAST-NEXT: sets 0
+; FAST-NEXT: retq
+BB:
+ %A31 = alloca i1, i32 0, align 1
+ %A = alloca i1, i32 0, align 1
+ %L2 = load i1, ptr %A, align 1
+ %L = load i1, ptr %A, align 1
+ store i1 poison, ptr null, align 1
+ store i1 false, ptr %A31, align 1
+ %LGV3 = load i64, ptr null, align 4
+ %G3 = getelementptr i1, ptr null, i1 %L2
+ %L4 = load i1, ptr %G3, align 1
+ %G1 = getelementptr i1, ptr null, i1 %L
+ %L9 = load i8, ptr %G1, align 1
+ %C10 = icmp sgt i8 0, %L9
+ %L31 = load i64, ptr %A31, align 4
+ store i1 false, ptr @G.1, align 1
+ %C4 = icmp ne i64 0, %LGV3
+ store ptr null, ptr %A31, align 8
+ store ptr null, ptr @G.5, align 8
+ %C5 = icmp sgt i64 %L3, 0
+ store i1 %C5, ptr null, align 1
+ store ptr null, ptr %G.5, align 8
+ store i1 %L4, ptr null, align 1
+ store i1 %C4, ptr %G.5, align 1
+ store i1 %C10, ptr null, align 1
+ ret void
+}
>From c9f596bccbbbe5c420c8ca7c6747f485b9d2471e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pawe=C5=82=20Bylica?= <pawel at hepcolgum.band>
Date: Mon, 14 Sep 2026 11:46:37 +0200
Subject: [PATCH 2/2] Replace the UB-dependent test with a reduction from real
code
arsenm asked the test not to depend on UB. pr63309.ll could not be cleaned in
place: it is a fuzzer reduction whose reproduction depends on the UB itself.
Changing only `store i1 poison` to `store i1 false` stops it reproducing,
because the poison kept that store distinct from the neighbouring
`store i1 false` instead of CSE-ing with it early; substituting `true`, an
existing value, a parameter or `freeze poison` all lose it too. Keeping the
poison but replacing the null addresses loses it as well, so both UB sources
are load-bearing.
Use the reproducer from #120631 instead. It comes from a real workload
(google/xls#1776) rather than a fuzzer, so its only UB is the null pointers
llvm-reduce introduced, and replacing those with a second pointer argument
leaves it reproducing. No poison, no null, no zero-sized alloca.
Verified both ways with an assertions build: without the scheduler fix it
aborts on the list and fast schedulers alike, and with the fix both pass.
Assisted-by: Claude Code
---
llvm/test/CodeGen/X86/pr120631.ll | 110 ++++++++++++++++++++++++++++++
llvm/test/CodeGen/X86/pr63309.ll | 85 -----------------------
2 files changed, 110 insertions(+), 85 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/pr120631.ll
delete mode 100644 llvm/test/CodeGen/X86/pr63309.ll
diff --git a/llvm/test/CodeGen/X86/pr120631.ll b/llvm/test/CodeGen/X86/pr120631.ll
new file mode 100644
index 0000000000000..eeedac40770f4
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr120631.ll
@@ -0,0 +1,110 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=RRLIST
+; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -pre-RA-sched=fast | FileCheck %s --check-prefix=FAST
+
+; Unfolding a load during scheduling replaces all uses of the folded node,
+; which can CSE-merge and delete a node still owned by another SUnit, leaving
+; it dangling. Both the list and fast schedulers unfold, so exercise both.
+; Reduced from a real workload (https://github.com/google/xls/issues/1776).
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+
+define i1 @pr120631(ptr %tmp_buffer, ptr %p2) {
+; RRLIST-LABEL: pr120631:
+; RRLIST: # %bb.0: # %entry
+; RRLIST-NEXT: movq (%rsi), %rax
+; RRLIST-NEXT: movq %rax, 16(%rdi)
+; RRLIST-NEXT: movzbl 8(%rsi), %eax
+; RRLIST-NEXT: movb %al, 24(%rdi)
+; RRLIST-NEXT: movzbl (%rdi), %eax
+; RRLIST-NEXT: movb %al, 25(%rdi)
+; RRLIST-NEXT: movb $0, 16(%rdi)
+; RRLIST-NEXT: movq (%rsi), %rcx
+; RRLIST-NEXT: movq 8(%rsi), %rdx
+; RRLIST-NEXT: movq %rdx, 24(%rdi)
+; RRLIST-NEXT: movq %rcx, 16(%rdi)
+; RRLIST-NEXT: movzbl (%rsi), %ecx
+; RRLIST-NEXT: movzbl (%rdi), %edx
+; RRLIST-NEXT: movzbl (%rdi), %r8d
+; RRLIST-NEXT: movb %r8b, 1(%rdi)
+; RRLIST-NEXT: movzbl (%rsi), %r8d
+; RRLIST-NEXT: andb $127, %r8b
+; RRLIST-NEXT: xorl %r9d, %r9d
+; RRLIST-NEXT: testb %cl, %cl
+; RRLIST-NEXT: movzbl %r8b, %r8d
+; RRLIST-NEXT: cmovel %r9d, %r8d
+; RRLIST-NEXT: addb %cl, %cl
+; RRLIST-NEXT: movzbl %cl, %ecx
+; RRLIST-NEXT: orl %edx, %ecx
+; RRLIST-NEXT: movb %al, (%rsi)
+; RRLIST-NEXT: movb %r8b, (%rdi)
+; RRLIST-NEXT: movw %cx, (%rsi)
+; RRLIST-NEXT: xorl %eax, %eax
+; RRLIST-NEXT: retq
+;
+; FAST-LABEL: pr120631:
+; FAST: # %bb.0: # %entry
+; FAST-NEXT: xorl %eax, %eax
+; FAST-NEXT: movq (%rsi), %rcx
+; FAST-NEXT: movq %rcx, 16(%rdi)
+; FAST-NEXT: movzbl 8(%rsi), %ecx
+; FAST-NEXT: movb $0, 16(%rdi)
+; FAST-NEXT: movzbl (%rdi), %edx
+; FAST-NEXT: movb %dl, 25(%rdi)
+; FAST-NEXT: movb %cl, 24(%rdi)
+; FAST-NEXT: movq (%rsi), %rcx
+; FAST-NEXT: movq 8(%rsi), %r8
+; FAST-NEXT: movq %rcx, 16(%rdi)
+; FAST-NEXT: movq %r8, 24(%rdi)
+; FAST-NEXT: movzbl (%rsi), %ecx
+; FAST-NEXT: movzbl (%rdi), %r8d
+; FAST-NEXT: movzbl (%rdi), %r9d
+; FAST-NEXT: movb %r9b, 1(%rdi)
+; FAST-NEXT: movzbl (%rsi), %r9d
+; FAST-NEXT: andb $127, %r9b
+; FAST-NEXT: leal (%rcx,%rcx), %r10d
+; FAST-NEXT: movzbl %r10b, %r10d
+; FAST-NEXT: orl %r8d, %r10d
+; FAST-NEXT: testb %cl, %cl
+; FAST-NEXT: movzbl %r9b, %ecx
+; FAST-NEXT: cmovel %eax, %ecx
+; FAST-NEXT: movb %dl, (%rsi)
+; FAST-NEXT: movb %cl, (%rdi)
+; FAST-NEXT: movw %r10w, (%rsi)
+; FAST-NEXT: xorl %eax, %eax
+; FAST-NEXT: retq
+entry:
+ %0 = ptrtoint ptr %tmp_buffer to i64
+ %1 = add i64 %0, 16
+ %2 = inttoptr i64 %1 to ptr
+ tail call void @llvm.memcpy.p0.p0.i64(ptr %2, ptr %p2, i64 9, i1 false)
+ %3 = getelementptr i8, ptr %2, i64 9
+ %4 = load i8, ptr %tmp_buffer, align 1
+ store i8 %4, ptr %3, align 1
+ %5 = load i8, ptr %p2, align 1
+ store i8 0, ptr %2, align 1
+ tail call void @llvm.memcpy.p0.p0.i64(ptr %2, ptr %p2, i64 16, i1 false)
+ %.val25 = load i1, ptr %p2, align 1
+ %.val26 = load i8, ptr %p2, align 1
+ %.val27 = load i1, ptr %tmp_buffer, align 1
+ %6 = shl i8 %.val26, 1
+ %7 = zext i1 %.val27 to i8
+ %8 = or i8 %6, %7
+ %.sroa.066.0..sroa.066.0..sroa.066.0..sroa.066.0. = load i8, ptr %tmp_buffer, align 1
+ %9 = add i64 %0, 1
+ %10 = inttoptr i64 %9 to ptr
+ tail call void @llvm.memcpy.p0.p0.i64(ptr %10, ptr %tmp_buffer, i64 1, i1 false)
+ %.val30 = load i8, ptr %p2, align 1
+ %11 = and i8 %.val30, 127
+ %12 = zext i8 %8 to i16
+ store i8 %.sroa.066.0..sroa.066.0..sroa.066.0..sroa.066.0., ptr %p2, align 1
+ %13 = select i1 %.val25, i8 %11, i8 0
+ store i8 %13, ptr %tmp_buffer, align 1
+ store i16 %12, ptr %p2, align 2
+ ret i1 false
+}
+
+; Function Attrs: nocallback nofree nounwind willreturn memory(argmem: readwrite)
+declare void @llvm.memcpy.p0.p0.i64(ptr noalias nocapture writeonly, ptr noalias nocapture readonly, i64, i1 immarg) #0
+
+attributes #0 = { nocallback nofree nounwind willreturn memory(argmem: readwrite) }
diff --git a/llvm/test/CodeGen/X86/pr63309.ll b/llvm/test/CodeGen/X86/pr63309.ll
deleted file mode 100644
index 4a89cb090fdc5..0000000000000
--- a/llvm/test/CodeGen/X86/pr63309.ll
+++ /dev/null
@@ -1,85 +0,0 @@
-; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=RRLIST
-; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu -pre-RA-sched=fast | FileCheck %s --check-prefix=FAST
-
-; Make sure this does not crash with "Node emitted out of order - early".
-; Unfolding a load during scheduling replaces all uses of the folded node,
-; which can CSE-merge and delete a node still referenced by another SUnit.
-; Both the list (ScheduleDAGRRList) and fast (ScheduleDAGFast) schedulers
-; perform this unfold, so exercise both.
-
- at G.1 = external global i1
- at G.5 = external global ptr
-
-define void @pr63309(ptr %G.5, i64 %L3) {
-; RRLIST-LABEL: pr63309:
-; RRLIST: # %bb.0: # %BB
-; RRLIST-NEXT: movzbl -{{[0-9]+}}(%rsp), %eax
-; RRLIST-NEXT: andl $1, %eax
-; RRLIST-NEXT: negq %rax
-; RRLIST-NEXT: movb $0, -{{[0-9]+}}(%rsp)
-; RRLIST-NEXT: movzbl (%rax), %eax
-; RRLIST-NEXT: movq G.1 at GOTPCREL(%rip), %rcx
-; RRLIST-NEXT: movq 0, %rdx
-; RRLIST-NEXT: movb $0, (%rcx)
-; RRLIST-NEXT: movq $0, -{{[0-9]+}}(%rsp)
-; RRLIST-NEXT: movq G.5 at GOTPCREL(%rip), %rcx
-; RRLIST-NEXT: movq $0, (%rcx)
-; RRLIST-NEXT: testq %rsi, %rsi
-; RRLIST-NEXT: setg 0
-; RRLIST-NEXT: testq %rdx, %rdx
-; RRLIST-NEXT: movq $0, (%rdi)
-; RRLIST-NEXT: movb %al, 0
-; RRLIST-NEXT: setne (%rdi)
-; RRLIST-NEXT: testb %al, %al
-; RRLIST-NEXT: sets 0
-; RRLIST-NEXT: retq
-;
-; FAST-LABEL: pr63309:
-; FAST: # %bb.0: # %BB
-; FAST-NEXT: movq G.1 at GOTPCREL(%rip), %rax
-; FAST-NEXT: movzbl -{{[0-9]+}}(%rsp), %ecx
-; FAST-NEXT: andl $1, %ecx
-; FAST-NEXT: negq %rcx
-; FAST-NEXT: movb $0, -{{[0-9]+}}(%rsp)
-; FAST-NEXT: movzbl (%rcx), %ecx
-; FAST-NEXT: movq 0, %rdx
-; FAST-NEXT: movb $0, (%rax)
-; FAST-NEXT: movq G.5 at GOTPCREL(%rip), %rax
-; FAST-NEXT: movq $0, (%rax)
-; FAST-NEXT: movq $0, -{{[0-9]+}}(%rsp)
-; FAST-NEXT: testq %rsi, %rsi
-; FAST-NEXT: setg 0
-; FAST-NEXT: testq %rdx, %rdx
-; FAST-NEXT: movq $0, (%rdi)
-; FAST-NEXT: movb %cl, 0
-; FAST-NEXT: setne (%rdi)
-; FAST-NEXT: testb %cl, %cl
-; FAST-NEXT: sets 0
-; FAST-NEXT: retq
-BB:
- %A31 = alloca i1, i32 0, align 1
- %A = alloca i1, i32 0, align 1
- %L2 = load i1, ptr %A, align 1
- %L = load i1, ptr %A, align 1
- store i1 poison, ptr null, align 1
- store i1 false, ptr %A31, align 1
- %LGV3 = load i64, ptr null, align 4
- %G3 = getelementptr i1, ptr null, i1 %L2
- %L4 = load i1, ptr %G3, align 1
- %G1 = getelementptr i1, ptr null, i1 %L
- %L9 = load i8, ptr %G1, align 1
- %C10 = icmp sgt i8 0, %L9
- %L31 = load i64, ptr %A31, align 4
- store i1 false, ptr @G.1, align 1
- %C4 = icmp ne i64 0, %LGV3
- store ptr null, ptr %A31, align 8
- store ptr null, ptr @G.5, align 8
- %C5 = icmp sgt i64 %L3, 0
- store i1 %C5, ptr null, align 1
- store ptr null, ptr %G.5, align 8
- store i1 %L4, ptr null, align 1
- store i1 %C4, ptr %G.5, align 1
- store i1 %C10, ptr null, align 1
- ret void
-}
More information about the llvm-commits
mailing list