[llvm] [SPIR-V] Duplicates Tracker accounts for possible changes in Constant usage after optimization (PR #110835)
Vyacheslav Levytskyy via llvm-commits
llvm-commits at lists.llvm.org
Thu Oct 3 03:00:11 PDT 2024
https://github.com/VyacheslavLevytskyy updated https://github.com/llvm/llvm-project/pull/110835
>From a8d82ab45309163dc7fcda956bebae1adbf41566 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Tue, 1 Oct 2024 04:56:31 -0700
Subject: [PATCH 1/3] support Branch Folding and If Conversion optimization
with analyzeBranch/removeBranch/insertBranch functions
---
llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp | 45 +++-
.../SPIRV/branching/analyze-branch-opt.ll | 250 ++++++++++++++++++
2 files changed, 283 insertions(+), 12 deletions(-)
create mode 100644 llvm/test/CodeGen/SPIRV/branching/analyze-branch-opt.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
index e8a6b4fdbae977..6a5c95122d7819 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
@@ -197,9 +197,9 @@ bool SPIRVInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
} else if (MI->getOpcode() == SPIRV::OpBranchConditional) {
Cond.push_back(MI->getOperand(0));
TBB = MI->getOperand(1).getMBB();
- if (MI->getNumOperands() == 3) {
- FBB = MI->getOperand(2).getMBB();
- }
+ FBB = MI->getOperand(2).getMBB();
+ for (unsigned I = 3, E = MI->getNumOperands(); I < E; ++I)
+ Cond.push_back(MI->getOperand(I));
return false;
} else {
return true;
@@ -212,9 +212,17 @@ bool SPIRVInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
// If \p BytesRemoved is non-null, report the change in code size from the
// removed instructions.
unsigned SPIRVInstrInfo::removeBranch(MachineBasicBlock &MBB,
- int *BytesRemoved) const {
- report_fatal_error("Branch removal not supported, as MBB info not propagated"
- " to OpPhi instructions. Try using -O0 instead.");
+ int * /*BytesRemoved*/) const {
+ MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
+ if (I == MBB.end())
+ return 0;
+
+ unsigned Opcode = I->getOpcode();
+ if (Opcode == SPIRV::OpBranch || Opcode == SPIRV::OpBranchConditional) {
+ I->eraseFromParent();
+ return 1;
+ }
+ return 0;
}
// Insert branch code into the end of the specified MachineBasicBlock. The
@@ -230,12 +238,25 @@ unsigned SPIRVInstrInfo::removeBranch(MachineBasicBlock &MBB,
//
// The CFG information in MBB.Predecessors and MBB.Successors must be valid
// before calling this function.
-unsigned SPIRVInstrInfo::insertBranch(
- MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
- ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
- report_fatal_error("Branch insertion not supported, as MBB info not "
- "propagated to OpPhi instructions. Try using "
- "-O0 instead.");
+unsigned SPIRVInstrInfo::insertBranch(MachineBasicBlock &MBB,
+ MachineBasicBlock *TBB,
+ MachineBasicBlock *FBB,
+ ArrayRef<MachineOperand> Cond,
+ const DebugLoc &DL,
+ int * /*BytesAdded*/) const {
+ if (!TBB)
+ return 0;
+ if (Cond.empty()) {
+ BuildMI(&MBB, DL, get(SPIRV::OpBranch)).addMBB(TBB);
+ } else {
+ auto MIB = BuildMI(&MBB, DL, get(SPIRV::OpBranchConditional))
+ .add(Cond[0])
+ .addMBB(TBB)
+ .addMBB(FBB);
+ for (unsigned i = 1; i < Cond.size(); ++i)
+ MIB.add(Cond[i]);
+ }
+ return 1;
}
void SPIRVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
diff --git a/llvm/test/CodeGen/SPIRV/branching/analyze-branch-opt.ll b/llvm/test/CodeGen/SPIRV/branching/analyze-branch-opt.ll
new file mode 100644
index 00000000000000..51018ff807a1ac
--- /dev/null
+++ b/llvm/test/CodeGen/SPIRV/branching/analyze-branch-opt.ll
@@ -0,0 +1,250 @@
+; The goal of this test case is to ensure that translation does not crash when during branching
+; optimization analyzeBranch() requires helper methods of removeBranch() and insertBranch()
+; to manage subsequent operations.
+
+; RUN: llc -O0 -mtriple=spirv64-unknown-linux %s -o - | FileCheck %s
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; RUN: llc -O0 -mtriple=spirv32-unknown-linux %s -o - | FileCheck %s
+; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
+
+; CHECK: OpFunction
+
+%struct = type { %arr }
+%arr = type { [3 x i64] }
+
+ at .str.6 = private unnamed_addr addrspace(1) constant [3 x i8] c", \00", align 1
+ at .str.20 = private unnamed_addr addrspace(1) constant [6 x i8] c"item(\00", align 1
+ at .str.21 = private unnamed_addr addrspace(1) constant [8 x i8] c"range: \00", align 1
+ at .str.22 = private unnamed_addr addrspace(1) constant [7 x i8] c", id: \00", align 1
+
+define spir_func i32 @foo(ptr addrspace(4) %Buf, ptr addrspace(4) %Item) {
+entry:
+ %ref.tmp = alloca %struct
+ %ref.tmp7 = alloca %struct
+ br label %for.cond.i
+
+for.cond.i: ; preds = %for.inc.i, %entry
+ %Len.0.i = phi i32 [ 0, %entry ], [ %inc.i, %for.inc.i ]
+ %idxprom.i = zext i32 %Len.0.i to i64
+ %arrayidx.i = getelementptr inbounds i8, ptr addrspace(1) @.str.20, i64 %idxprom.i
+ %0 = load i8, ptr addrspace(1) %arrayidx.i
+ %cmp.not.i = icmp eq i8 %0, 0
+ br i1 %cmp.not.i, label %for.cond1.i, label %for.inc.i
+
+for.inc.i: ; preds = %for.cond.i
+ %inc.i = add i32 %Len.0.i, 1
+ br label %for.cond.i, !llvm.loop !1
+
+for.cond1.i: ; preds = %for.body3.i, %for.cond.i
+ %I.0.i = phi i32 [ %inc9.i, %for.body3.i ], [ 0, %for.cond.i ]
+ %cmp2.i = icmp ult i32 %I.0.i, %Len.0.i
+ br i1 %cmp2.i, label %for.body3.i, label %for.cond.preheader
+
+for.cond.preheader: ; preds = %for.cond1.i
+ %MIndex.i = getelementptr inbounds i8, ptr addrspace(4) %Item, i64 24
+ br label %for.cond
+
+for.body3.i: ; preds = %for.cond1.i
+ %idxprom4.i = zext i32 %I.0.i to i64
+ %arrayidx5.i = getelementptr inbounds i8, ptr addrspace(1) @.str.20, i64 %idxprom4.i
+ %1 = load i8, ptr addrspace(1) %arrayidx5.i
+ %arrayidx7.i = getelementptr inbounds i8, ptr addrspace(4) %Buf, i64 %idxprom4.i
+ store i8 %1, ptr addrspace(4) %arrayidx7.i
+ %inc9.i = add nuw i32 %I.0.i, 1
+ br label %for.cond1.i, !llvm.loop !2
+
+for.cond: ; preds = %exit, %for.cond.preheader
+ %Len.0 = phi i32 [ %add9, %exit ], [ %Len.0.i, %for.cond.preheader ]
+ %I.0 = phi i32 [ %inc, %exit ], [ 0, %for.cond.preheader ]
+ %cmp = icmp ult i32 %I.0, 2
+ br i1 %cmp, label %for.body, label %for.cond.cleanup
+
+for.cond.cleanup: ; preds = %for.cond
+ %inc10 = add i32 %Len.0, 1
+ %idxprom = zext i32 %Len.0 to i64
+ %arrayidx = getelementptr inbounds i8, ptr addrspace(4) %Buf, i64 %idxprom
+ store i8 41, ptr addrspace(4) %arrayidx
+ ret i32 %inc10
+
+for.body: ; preds = %for.cond
+ %idx.ext = zext i32 %Len.0 to i64
+ %add.ptr = getelementptr inbounds i8, ptr addrspace(4) %Buf, i64 %idx.ext
+ %cmp1 = icmp eq i32 %I.0, 0
+ %cond = select i1 %cmp1, ptr addrspace(1) @.str.21, ptr addrspace(1) @.str.22
+ br label %for.cond.i25
+
+for.cond.i25: ; preds = %for.inc.i30, %for.body
+ %Len.0.i26 = phi i32 [ 0, %for.body ], [ %inc.i31, %for.inc.i30 ]
+ %idxprom.i27 = zext i32 %Len.0.i26 to i64
+ %arrayidx.i28 = getelementptr inbounds i8, ptr addrspace(1) %cond, i64 %idxprom.i27
+ %2 = load i8, ptr addrspace(1) %arrayidx.i28
+ %cmp.not.i29 = icmp eq i8 %2, 0
+ br i1 %cmp.not.i29, label %for.cond1.i33, label %for.inc.i30
+
+for.inc.i30: ; preds = %for.cond.i25
+ %inc.i31 = add i32 %Len.0.i26, 1
+ br label %for.cond.i25, !llvm.loop !1
+
+for.cond1.i33: ; preds = %for.body3.i36, %for.cond.i25
+ %I.0.i34 = phi i32 [ %inc9.i40, %for.body3.i36 ], [ 0, %for.cond.i25 ]
+ %cmp2.i35 = icmp ult i32 %I.0.i34, %Len.0.i26
+ br i1 %cmp2.i35, label %for.body3.i36, label %detail.exit
+
+for.body3.i36: ; preds = %for.cond1.i33
+ %idxprom4.i37 = zext i32 %I.0.i34 to i64
+ %arrayidx5.i38 = getelementptr inbounds i8, ptr addrspace(1) %cond, i64 %idxprom4.i37
+ %3 = load i8, ptr addrspace(1) %arrayidx5.i38
+ %arrayidx7.i39 = getelementptr inbounds i8, ptr addrspace(4) %add.ptr, i64 %idxprom4.i37
+ store i8 %3, ptr addrspace(4) %arrayidx7.i39
+ %inc9.i40 = add nuw i32 %I.0.i34, 1
+ br label %for.cond1.i33, !llvm.loop !2
+
+detail.exit: ; preds = %for.cond1.i33
+ %add3 = add i32 %Len.0, %Len.0.i26
+ %idx.ext4 = zext i32 %add3 to i64
+ %add.ptr5 = getelementptr inbounds i8, ptr addrspace(4) %Buf, i64 %idx.ext4
+ br i1 %cmp1, label %cond.true, label %cond.false
+
+cond.true: ; preds = %detail.exit
+ call void @llvm.memcpy.p0.p4.i64(ptr align 8 %ref.tmp7, ptr addrspace(4) align 8 %Item, i64 24, i1 false)
+ call void @llvm.memset.p0.i64(ptr align 8 %ref.tmp, i8 0, i64 24, i1 false)
+ br label %for.cond.i42
+
+for.cond.i42: ; preds = %for.body.i, %cond.true
+ %i.0.i = phi i32 [ 0, %cond.true ], [ %inc.i45, %for.body.i ]
+ %cmp.i = icmp ult i32 %i.0.i, 3
+ br i1 %cmp.i, label %for.body.i, label %cond.end
+
+for.body.i: ; preds = %for.cond.i42
+ %idxprom.i43 = zext nneg i32 %i.0.i to i64
+ %arrayidx.i44 = getelementptr inbounds [3 x i64], ptr %ref.tmp7, i64 0, i64 %idxprom.i43
+ %4 = load i64, ptr %arrayidx.i44, align 8
+ %arrayidx.i.i = getelementptr inbounds [3 x i64], ptr %ref.tmp, i64 0, i64 %idxprom.i43
+ store i64 %4, ptr %arrayidx.i.i, align 8
+ %inc.i45 = add nuw nsw i32 %i.0.i, 1
+ br label %for.cond.i42, !llvm.loop !3
+
+cond.false: ; preds = %detail.exit
+ call void @llvm.memcpy.p0.p4.i64(ptr align 8 %ref.tmp, ptr addrspace(4) align 8 %MIndex.i, i64 24, i1 false)
+ br label %cond.end
+
+cond.end: ; preds = %cond.false, %for.cond.i42
+ store i8 123, ptr addrspace(4) %add.ptr5
+ br label %for.cond.i46
+
+for.cond.i46: ; preds = %for.inc.i52, %cond.end
+ %Len.0.i47 = phi i32 [ 1, %cond.end ], [ %Len.1.i, %for.inc.i52 ]
+ %I.0.i48 = phi i32 [ 0, %cond.end ], [ %inc7.i, %for.inc.i52 ]
+ %cmp.i49 = icmp ult i32 %I.0.i48, 3
+ br i1 %cmp.i49, label %for.body.i50, label %exit
+
+for.body.i50: ; preds = %for.cond.i46
+ %idxprom.i.i = zext nneg i32 %I.0.i48 to i64
+ %arrayidx.i.i51 = getelementptr inbounds [3 x i64], ptr %ref.tmp, i64 0, i64 %idxprom.i.i
+ %5 = load i64, ptr %arrayidx.i.i51, align 8
+ %idx.ext.i = zext i32 %Len.0.i47 to i64
+ %add.ptr.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr5, i64 %idx.ext.i
+ br label %do.body.i.i.i
+
+do.body.i.i.i: ; preds = %do.body.i.i.i, %for.body.i50
+ %Val.addr.0.i.i.i = phi i64 [ %5, %for.body.i50 ], [ %div.i.i.i, %do.body.i.i.i ]
+ %NumDigits.0.i.i.i = phi i32 [ 0, %for.body.i50 ], [ %inc.i.i.i, %do.body.i.i.i ]
+ %Val.addr.0.i.i.i.frozen = freeze i64 %Val.addr.0.i.i.i
+ %div.i.i.i = udiv i64 %Val.addr.0.i.i.i.frozen, 10
+ %6 = mul i64 %div.i.i.i, 10
+ %rem.i.i.i.decomposed = sub i64 %Val.addr.0.i.i.i.frozen, %6
+ %7 = trunc i64 %rem.i.i.i.decomposed to i8
+ %retval.0.i.i.i.i = or disjoint i8 %7, 48
+ %inc.i.i.i = add i32 %NumDigits.0.i.i.i, 1
+ %idxprom.i.i.i = zext i32 %NumDigits.0.i.i.i to i64
+ %arrayidx.i.i.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr.i, i64 %idxprom.i.i.i
+ store i8 %retval.0.i.i.i.i, ptr addrspace(4) %arrayidx.i.i.i
+ %tobool.not.i.i.i = icmp ult i64 %Val.addr.0.i.i.i, 10
+ br i1 %tobool.not.i.i.i, label %while.cond.i.i.i, label %do.body.i.i.i, !llvm.loop !4
+
+while.cond.i.i.i: ; preds = %while.body.i.i.i, %do.body.i.i.i
+ %J.0.i.i.i = phi i32 [ %inc.i54.i.i, %while.body.i.i.i ], [ 0, %do.body.i.i.i ]
+ %I.0.in.i.i.i = phi i32 [ %I.0.i.i.i, %while.body.i.i.i ], [ %inc.i.i.i, %do.body.i.i.i ]
+ %I.0.i.i.i = add i32 %I.0.in.i.i.i, -1
+ %cmp.i.i.i = icmp sgt i32 %I.0.i.i.i, %J.0.i.i.i
+ br i1 %cmp.i.i.i, label %while.body.i.i.i, label %enable.exit
+
+while.body.i.i.i: ; preds = %while.cond.i.i.i
+ %idxprom.i52.i.i = sext i32 %I.0.i.i.i to i64
+ %arrayidx.i53.i.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr.i, i64 %idxprom.i52.i.i
+ %8 = load i8, ptr addrspace(4) %arrayidx.i53.i.i
+ %idxprom1.i.i.i = zext nneg i32 %J.0.i.i.i to i64
+ %arrayidx2.i.i.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr.i, i64 %idxprom1.i.i.i
+ %9 = load i8, ptr addrspace(4) %arrayidx2.i.i.i
+ store i8 %9, ptr addrspace(4) %arrayidx.i53.i.i
+ store i8 %8, ptr addrspace(4) %arrayidx2.i.i.i
+ %inc.i54.i.i = add nuw nsw i32 %J.0.i.i.i, 1
+ br label %while.cond.i.i.i, !llvm.loop !5
+
+enable.exit: ; preds = %while.cond.i.i.i
+ %add.i = add i32 %Len.0.i47, %inc.i.i.i
+ %cmp2.not.i = icmp eq i32 %I.0.i48, 2
+ br i1 %cmp2.not.i, label %for.inc.i52, label %if.then.i
+
+if.then.i: ; preds = %enable.exit
+ %idx.ext3.i = zext i32 %add.i to i64
+ %add.ptr4.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr5, i64 %idx.ext3.i
+ br label %for.cond.i.i
+
+for.cond.i.i: ; preds = %for.inc.i.i, %if.then.i
+ %Len.0.i.i = phi i32 [ 0, %if.then.i ], [ %inc.i.i, %for.inc.i.i ]
+ %idxprom.i24.i = zext i32 %Len.0.i.i to i64
+ %arrayidx.i25.i = getelementptr inbounds i8, ptr addrspace(1) @.str.6, i64 %idxprom.i24.i
+ %10 = load i8, ptr addrspace(1) %arrayidx.i25.i
+ %cmp.not.i.i = icmp eq i8 %10, 0
+ br i1 %cmp.not.i.i, label %for.cond1.i.i, label %for.inc.i.i
+
+for.inc.i.i: ; preds = %for.cond.i.i
+ %inc.i.i = add i32 %Len.0.i.i, 1
+ br label %for.cond.i.i, !llvm.loop !1
+
+for.cond1.i.i: ; preds = %for.body3.i.i, %for.cond.i.i
+ %I.0.i.i = phi i32 [ %inc9.i.i, %for.body3.i.i ], [ 0, %for.cond.i.i ]
+ %cmp2.i.i = icmp ult i32 %I.0.i.i, %Len.0.i.i
+ br i1 %cmp2.i.i, label %for.body3.i.i, label %append.exit
+
+for.body3.i.i: ; preds = %for.cond1.i.i
+ %idxprom4.i.i = zext i32 %I.0.i.i to i64
+ %arrayidx5.i.i = getelementptr inbounds i8, ptr addrspace(1) @.str.6, i64 %idxprom4.i.i
+ %11 = load i8, ptr addrspace(1) %arrayidx5.i.i
+ %arrayidx7.i.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr4.i, i64 %idxprom4.i.i
+ store i8 %11, ptr addrspace(4) %arrayidx7.i.i
+ %inc9.i.i = add nuw i32 %I.0.i.i, 1
+ br label %for.cond1.i.i, !llvm.loop !2
+
+append.exit: ; preds = %for.cond1.i.i
+ %add6.i = add i32 %add.i, %Len.0.i.i
+ br label %for.inc.i52
+
+for.inc.i52: ; preds = %append.exit, %enable.exit
+ %Len.1.i = phi i32 [ %add6.i, %append.exit ], [ %add.i, %enable.exit ]
+ %inc7.i = add nuw nsw i32 %I.0.i48, 1
+ br label %for.cond.i46, !llvm.loop !6
+
+exit: ; preds = %for.cond.i46
+ %inc8.i = add i32 %Len.0.i47, 1
+ %idxprom9.i = zext i32 %Len.0.i47 to i64
+ %arrayidx10.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr5, i64 %idxprom9.i
+ store i8 125, ptr addrspace(4) %arrayidx10.i
+ %add9 = add i32 %add3, %inc8.i
+ %inc = add nuw nsw i32 %I.0, 1
+ br label %for.cond, !llvm.loop !7
+}
+
+declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
+declare void @llvm.memcpy.p0.p4.i64(ptr noalias nocapture writeonly, ptr addrspace(4) noalias nocapture readonly, i64, i1 immarg)
+
+!0 = !{!"llvm.loop.mustprogress"}
+!1 = distinct !{!1, !0}
+!2 = distinct !{!2, !0}
+!3 = distinct !{!3, !0}
+!4 = distinct !{!4, !0}
+!5 = distinct !{!5, !0}
+!6 = distinct !{!6, !0}
+!7 = distinct !{!7, !0}
>From 1d1021f13632ce127187d9d3f1ac3f38ea2813d0 Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Wed, 2 Oct 2024 05:26:21 -0700
Subject: [PATCH 2/3] Duplicates Tracket accounts for possible changes in
Constant usage after optimization
---
.../Target/SPIRV/SPIRVDuplicatesTracker.cpp | 49 ++++++++++---------
.../lib/Target/SPIRV/SPIRVDuplicatesTracker.h | 15 ++++--
llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h | 3 +-
llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp | 2 +-
4 files changed, 40 insertions(+), 29 deletions(-)
diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp
index 832ca0ba5a82d7..b82c2538a81368 100644
--- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "SPIRVDuplicatesTracker.h"
+#include "SPIRVInstrInfo.h"
#define DEBUG_TYPE "build-dep-graph"
@@ -19,13 +20,14 @@ using namespace llvm;
template <typename T>
void SPIRVGeneralDuplicatesTracker::prebuildReg2Entry(
- SPIRVDuplicatesTracker<T> &DT, SPIRVReg2EntryTy &Reg2Entry) {
+ SPIRVDuplicatesTracker<T> &DT, SPIRVReg2EntryTy &Reg2Entry,
+ const SPIRVInstrInfo *TII) {
for (auto &TPair : DT.getAllUses()) {
for (auto &RegPair : TPair.second) {
const MachineFunction *MF = RegPair.first;
Register R = RegPair.second;
MachineInstr *MI = MF->getRegInfo().getUniqueVRegDef(R);
- if (!MI)
+ if (!MI || (TPair.second.getIsConst() && !TII->isConstantInstr(*MI)))
continue;
Reg2Entry[&MI->getOperand(0)] = &TPair.second;
}
@@ -33,16 +35,16 @@ void SPIRVGeneralDuplicatesTracker::prebuildReg2Entry(
}
void SPIRVGeneralDuplicatesTracker::buildDepsGraph(
- std::vector<SPIRV::DTSortableEntry *> &Graph,
+ std::vector<SPIRV::DTSortableEntry *> &Graph, const SPIRVInstrInfo *TII,
MachineModuleInfo *MMI = nullptr) {
SPIRVReg2EntryTy Reg2Entry;
- prebuildReg2Entry(TT, Reg2Entry);
- prebuildReg2Entry(CT, Reg2Entry);
- prebuildReg2Entry(GT, Reg2Entry);
- prebuildReg2Entry(FT, Reg2Entry);
- prebuildReg2Entry(AT, Reg2Entry);
- prebuildReg2Entry(MT, Reg2Entry);
- prebuildReg2Entry(ST, Reg2Entry);
+ prebuildReg2Entry(TT, Reg2Entry, TII);
+ prebuildReg2Entry(CT, Reg2Entry, TII);
+ prebuildReg2Entry(GT, Reg2Entry, TII);
+ prebuildReg2Entry(FT, Reg2Entry, TII);
+ prebuildReg2Entry(AT, Reg2Entry, TII);
+ prebuildReg2Entry(MT, Reg2Entry, TII);
+ prebuildReg2Entry(ST, Reg2Entry, TII);
for (auto &Op2E : Reg2Entry) {
SPIRV::DTSortableEntry *E = Op2E.second;
@@ -65,20 +67,19 @@ void SPIRVGeneralDuplicatesTracker::buildDepsGraph(
if (MI->getOpcode() == SPIRV::OpConstantFunctionPointerINTEL && i == 2)
continue;
MachineOperand *RegOp = &VRegDef->getOperand(0);
- LLVM_DEBUG({
- if (Reg2Entry.count(RegOp) == 0 &&
- (MI->getOpcode() != SPIRV::OpVariable || i != 3)) {
- dbgs() << "Unexpected pattern while building a dependency "
- "graph.\nInstruction: ";
- MI->print(dbgs());
- dbgs() << "Operand: ";
- Op.print(dbgs());
- dbgs() << "\nOperand definition: ";
- VRegDef->print(dbgs());
- }
- });
- assert((MI->getOpcode() == SPIRV::OpVariable && i == 3) ||
- Reg2Entry.count(RegOp));
+ if (Reg2Entry.count(RegOp) == 0 &&
+ (MI->getOpcode() != SPIRV::OpVariable || i != 3)) {
+ std::string DiagMsg;
+ raw_string_ostream OS(DiagMsg);
+ OS << "Unexpected pattern while building a dependency "
+ "graph.\nInstruction: ";
+ MI->print(OS);
+ OS << "Operand: ";
+ Op.print(OS);
+ OS << "\nOperand definition: ";
+ VRegDef->print(OS);
+ report_fatal_error(DiagMsg.c_str());
+ }
if (Reg2Entry.count(RegOp))
E->addDep(Reg2Entry[RegOp]);
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
index a37e65a47eda04..47391bf63b5947 100644
--- a/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
+++ b/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.h
@@ -26,6 +26,7 @@
namespace llvm {
namespace SPIRV {
+class SPIRVInstrInfo;
// NOTE: using MapVector instead of DenseMap because it helps getting
// everything ordered in a stable manner for a price of extra (NumKeys)*PtrSize
// memory and expensive removals which do not happen anyway.
@@ -35,8 +36,9 @@ class DTSortableEntry : public MapVector<const MachineFunction *, Register> {
struct FlagsTy {
unsigned IsFunc : 1;
unsigned IsGV : 1;
+ unsigned IsConst : 1;
// NOTE: bit-field default init is a C++20 feature.
- FlagsTy() : IsFunc(0), IsGV(0) {}
+ FlagsTy() : IsFunc(0), IsGV(0), IsConst(0) {}
};
FlagsTy Flags;
@@ -45,8 +47,10 @@ class DTSortableEntry : public MapVector<const MachineFunction *, Register> {
// require hoisting of params as well.
bool getIsFunc() const { return Flags.IsFunc; }
bool getIsGV() const { return Flags.IsGV; }
+ bool getIsConst() const { return Flags.IsConst; }
void setIsFunc(bool V) { Flags.IsFunc = V; }
void setIsGV(bool V) { Flags.IsGV = V; }
+ void setIsConst(bool V) { Flags.IsConst = V; }
const SmallVector<DTSortableEntry *, 2> &getDeps() const { return Deps; }
void addDep(DTSortableEntry *E) { Deps.push_back(E); }
@@ -160,6 +164,10 @@ template <typename KeyTy> class SPIRVDuplicatesTrackerBase {
typename std::remove_const<
typename std::remove_pointer<KeyTy>::type>::type>())
Storage[V].setIsGV(true);
+ if (std::is_same<Constant,
+ typename std::remove_const<
+ typename std::remove_pointer<KeyTy>::type>::type>())
+ Storage[V].setIsConst(true);
}
Register find(KeyTy V, const MachineFunction *MF) const {
@@ -211,11 +219,12 @@ class SPIRVGeneralDuplicatesTracker {
template <typename T>
void prebuildReg2Entry(SPIRVDuplicatesTracker<T> &DT,
- SPIRVReg2EntryTy &Reg2Entry);
+ SPIRVReg2EntryTy &Reg2Entry,
+ const SPIRVInstrInfo *TII);
public:
void buildDepsGraph(std::vector<SPIRV::DTSortableEntry *> &Graph,
- MachineModuleInfo *MMI);
+ const SPIRVInstrInfo *TII, MachineModuleInfo *MMI);
void add(const Type *Ty, const MachineFunction *MF, Register R) {
TT.add(unifyPtrType(Ty), MF, R);
diff --git a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
index ace5cfe91ebe48..d301e119e16c8e 100644
--- a/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
+++ b/llvm/lib/Target/SPIRV/SPIRVGlobalRegistry.h
@@ -152,8 +152,9 @@ class SPIRVGlobalRegistry {
}
void buildDepsGraph(std::vector<SPIRV::DTSortableEntry *> &Graph,
+ const SPIRVInstrInfo *TII,
MachineModuleInfo *MMI = nullptr) {
- DT.buildDepsGraph(Graph, MMI);
+ DT.buildDepsGraph(Graph, TII, MMI);
}
void setBound(unsigned V) { Bound = V; }
diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
index 8908d8965b67c5..2083f18da9c590 100644
--- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp
@@ -282,7 +282,7 @@ void SPIRVModuleAnalysis::collectGlobalEntities(
void SPIRVModuleAnalysis::processDefInstrs(const Module &M) {
std::vector<SPIRV::DTSortableEntry *> DepsGraph;
- GR->buildDepsGraph(DepsGraph, SPVDumpDeps ? MMI : nullptr);
+ GR->buildDepsGraph(DepsGraph, TII, SPVDumpDeps ? MMI : nullptr);
collectGlobalEntities(
DepsGraph, SPIRV::MB_TypeConstVars,
>From 04b62315618c87d4a9240eddb7a0c7939c7a978d Mon Sep 17 00:00:00 2001
From: "Levytskyy, Vyacheslav" <vyacheslav.levytskyy at intel.com>
Date: Thu, 3 Oct 2024 02:59:59 -0700
Subject: [PATCH 3/3] detach from #110653
---
llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp | 45 +---
.../SPIRV/branching/analyze-branch-opt.ll | 250 ------------------
2 files changed, 12 insertions(+), 283 deletions(-)
delete mode 100644 llvm/test/CodeGen/SPIRV/branching/analyze-branch-opt.ll
diff --git a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
index 6a5c95122d7819..e8a6b4fdbae977 100644
--- a/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVInstrInfo.cpp
@@ -197,9 +197,9 @@ bool SPIRVInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
} else if (MI->getOpcode() == SPIRV::OpBranchConditional) {
Cond.push_back(MI->getOperand(0));
TBB = MI->getOperand(1).getMBB();
- FBB = MI->getOperand(2).getMBB();
- for (unsigned I = 3, E = MI->getNumOperands(); I < E; ++I)
- Cond.push_back(MI->getOperand(I));
+ if (MI->getNumOperands() == 3) {
+ FBB = MI->getOperand(2).getMBB();
+ }
return false;
} else {
return true;
@@ -212,17 +212,9 @@ bool SPIRVInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
// If \p BytesRemoved is non-null, report the change in code size from the
// removed instructions.
unsigned SPIRVInstrInfo::removeBranch(MachineBasicBlock &MBB,
- int * /*BytesRemoved*/) const {
- MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
- if (I == MBB.end())
- return 0;
-
- unsigned Opcode = I->getOpcode();
- if (Opcode == SPIRV::OpBranch || Opcode == SPIRV::OpBranchConditional) {
- I->eraseFromParent();
- return 1;
- }
- return 0;
+ int *BytesRemoved) const {
+ report_fatal_error("Branch removal not supported, as MBB info not propagated"
+ " to OpPhi instructions. Try using -O0 instead.");
}
// Insert branch code into the end of the specified MachineBasicBlock. The
@@ -238,25 +230,12 @@ unsigned SPIRVInstrInfo::removeBranch(MachineBasicBlock &MBB,
//
// The CFG information in MBB.Predecessors and MBB.Successors must be valid
// before calling this function.
-unsigned SPIRVInstrInfo::insertBranch(MachineBasicBlock &MBB,
- MachineBasicBlock *TBB,
- MachineBasicBlock *FBB,
- ArrayRef<MachineOperand> Cond,
- const DebugLoc &DL,
- int * /*BytesAdded*/) const {
- if (!TBB)
- return 0;
- if (Cond.empty()) {
- BuildMI(&MBB, DL, get(SPIRV::OpBranch)).addMBB(TBB);
- } else {
- auto MIB = BuildMI(&MBB, DL, get(SPIRV::OpBranchConditional))
- .add(Cond[0])
- .addMBB(TBB)
- .addMBB(FBB);
- for (unsigned i = 1; i < Cond.size(); ++i)
- MIB.add(Cond[i]);
- }
- return 1;
+unsigned SPIRVInstrInfo::insertBranch(
+ MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
+ ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
+ report_fatal_error("Branch insertion not supported, as MBB info not "
+ "propagated to OpPhi instructions. Try using "
+ "-O0 instead.");
}
void SPIRVInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
diff --git a/llvm/test/CodeGen/SPIRV/branching/analyze-branch-opt.ll b/llvm/test/CodeGen/SPIRV/branching/analyze-branch-opt.ll
deleted file mode 100644
index 51018ff807a1ac..00000000000000
--- a/llvm/test/CodeGen/SPIRV/branching/analyze-branch-opt.ll
+++ /dev/null
@@ -1,250 +0,0 @@
-; The goal of this test case is to ensure that translation does not crash when during branching
-; optimization analyzeBranch() requires helper methods of removeBranch() and insertBranch()
-; to manage subsequent operations.
-
-; RUN: llc -O0 -mtriple=spirv64-unknown-linux %s -o - | FileCheck %s
-; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv64-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-
-; RUN: llc -O0 -mtriple=spirv32-unknown-linux %s -o - | FileCheck %s
-; TODO: %if spirv-tools %{ llc -O0 -mtriple=spirv32-unknown-unknown %s -o - -filetype=obj | spirv-val %}
-
-; CHECK: OpFunction
-
-%struct = type { %arr }
-%arr = type { [3 x i64] }
-
- at .str.6 = private unnamed_addr addrspace(1) constant [3 x i8] c", \00", align 1
- at .str.20 = private unnamed_addr addrspace(1) constant [6 x i8] c"item(\00", align 1
- at .str.21 = private unnamed_addr addrspace(1) constant [8 x i8] c"range: \00", align 1
- at .str.22 = private unnamed_addr addrspace(1) constant [7 x i8] c", id: \00", align 1
-
-define spir_func i32 @foo(ptr addrspace(4) %Buf, ptr addrspace(4) %Item) {
-entry:
- %ref.tmp = alloca %struct
- %ref.tmp7 = alloca %struct
- br label %for.cond.i
-
-for.cond.i: ; preds = %for.inc.i, %entry
- %Len.0.i = phi i32 [ 0, %entry ], [ %inc.i, %for.inc.i ]
- %idxprom.i = zext i32 %Len.0.i to i64
- %arrayidx.i = getelementptr inbounds i8, ptr addrspace(1) @.str.20, i64 %idxprom.i
- %0 = load i8, ptr addrspace(1) %arrayidx.i
- %cmp.not.i = icmp eq i8 %0, 0
- br i1 %cmp.not.i, label %for.cond1.i, label %for.inc.i
-
-for.inc.i: ; preds = %for.cond.i
- %inc.i = add i32 %Len.0.i, 1
- br label %for.cond.i, !llvm.loop !1
-
-for.cond1.i: ; preds = %for.body3.i, %for.cond.i
- %I.0.i = phi i32 [ %inc9.i, %for.body3.i ], [ 0, %for.cond.i ]
- %cmp2.i = icmp ult i32 %I.0.i, %Len.0.i
- br i1 %cmp2.i, label %for.body3.i, label %for.cond.preheader
-
-for.cond.preheader: ; preds = %for.cond1.i
- %MIndex.i = getelementptr inbounds i8, ptr addrspace(4) %Item, i64 24
- br label %for.cond
-
-for.body3.i: ; preds = %for.cond1.i
- %idxprom4.i = zext i32 %I.0.i to i64
- %arrayidx5.i = getelementptr inbounds i8, ptr addrspace(1) @.str.20, i64 %idxprom4.i
- %1 = load i8, ptr addrspace(1) %arrayidx5.i
- %arrayidx7.i = getelementptr inbounds i8, ptr addrspace(4) %Buf, i64 %idxprom4.i
- store i8 %1, ptr addrspace(4) %arrayidx7.i
- %inc9.i = add nuw i32 %I.0.i, 1
- br label %for.cond1.i, !llvm.loop !2
-
-for.cond: ; preds = %exit, %for.cond.preheader
- %Len.0 = phi i32 [ %add9, %exit ], [ %Len.0.i, %for.cond.preheader ]
- %I.0 = phi i32 [ %inc, %exit ], [ 0, %for.cond.preheader ]
- %cmp = icmp ult i32 %I.0, 2
- br i1 %cmp, label %for.body, label %for.cond.cleanup
-
-for.cond.cleanup: ; preds = %for.cond
- %inc10 = add i32 %Len.0, 1
- %idxprom = zext i32 %Len.0 to i64
- %arrayidx = getelementptr inbounds i8, ptr addrspace(4) %Buf, i64 %idxprom
- store i8 41, ptr addrspace(4) %arrayidx
- ret i32 %inc10
-
-for.body: ; preds = %for.cond
- %idx.ext = zext i32 %Len.0 to i64
- %add.ptr = getelementptr inbounds i8, ptr addrspace(4) %Buf, i64 %idx.ext
- %cmp1 = icmp eq i32 %I.0, 0
- %cond = select i1 %cmp1, ptr addrspace(1) @.str.21, ptr addrspace(1) @.str.22
- br label %for.cond.i25
-
-for.cond.i25: ; preds = %for.inc.i30, %for.body
- %Len.0.i26 = phi i32 [ 0, %for.body ], [ %inc.i31, %for.inc.i30 ]
- %idxprom.i27 = zext i32 %Len.0.i26 to i64
- %arrayidx.i28 = getelementptr inbounds i8, ptr addrspace(1) %cond, i64 %idxprom.i27
- %2 = load i8, ptr addrspace(1) %arrayidx.i28
- %cmp.not.i29 = icmp eq i8 %2, 0
- br i1 %cmp.not.i29, label %for.cond1.i33, label %for.inc.i30
-
-for.inc.i30: ; preds = %for.cond.i25
- %inc.i31 = add i32 %Len.0.i26, 1
- br label %for.cond.i25, !llvm.loop !1
-
-for.cond1.i33: ; preds = %for.body3.i36, %for.cond.i25
- %I.0.i34 = phi i32 [ %inc9.i40, %for.body3.i36 ], [ 0, %for.cond.i25 ]
- %cmp2.i35 = icmp ult i32 %I.0.i34, %Len.0.i26
- br i1 %cmp2.i35, label %for.body3.i36, label %detail.exit
-
-for.body3.i36: ; preds = %for.cond1.i33
- %idxprom4.i37 = zext i32 %I.0.i34 to i64
- %arrayidx5.i38 = getelementptr inbounds i8, ptr addrspace(1) %cond, i64 %idxprom4.i37
- %3 = load i8, ptr addrspace(1) %arrayidx5.i38
- %arrayidx7.i39 = getelementptr inbounds i8, ptr addrspace(4) %add.ptr, i64 %idxprom4.i37
- store i8 %3, ptr addrspace(4) %arrayidx7.i39
- %inc9.i40 = add nuw i32 %I.0.i34, 1
- br label %for.cond1.i33, !llvm.loop !2
-
-detail.exit: ; preds = %for.cond1.i33
- %add3 = add i32 %Len.0, %Len.0.i26
- %idx.ext4 = zext i32 %add3 to i64
- %add.ptr5 = getelementptr inbounds i8, ptr addrspace(4) %Buf, i64 %idx.ext4
- br i1 %cmp1, label %cond.true, label %cond.false
-
-cond.true: ; preds = %detail.exit
- call void @llvm.memcpy.p0.p4.i64(ptr align 8 %ref.tmp7, ptr addrspace(4) align 8 %Item, i64 24, i1 false)
- call void @llvm.memset.p0.i64(ptr align 8 %ref.tmp, i8 0, i64 24, i1 false)
- br label %for.cond.i42
-
-for.cond.i42: ; preds = %for.body.i, %cond.true
- %i.0.i = phi i32 [ 0, %cond.true ], [ %inc.i45, %for.body.i ]
- %cmp.i = icmp ult i32 %i.0.i, 3
- br i1 %cmp.i, label %for.body.i, label %cond.end
-
-for.body.i: ; preds = %for.cond.i42
- %idxprom.i43 = zext nneg i32 %i.0.i to i64
- %arrayidx.i44 = getelementptr inbounds [3 x i64], ptr %ref.tmp7, i64 0, i64 %idxprom.i43
- %4 = load i64, ptr %arrayidx.i44, align 8
- %arrayidx.i.i = getelementptr inbounds [3 x i64], ptr %ref.tmp, i64 0, i64 %idxprom.i43
- store i64 %4, ptr %arrayidx.i.i, align 8
- %inc.i45 = add nuw nsw i32 %i.0.i, 1
- br label %for.cond.i42, !llvm.loop !3
-
-cond.false: ; preds = %detail.exit
- call void @llvm.memcpy.p0.p4.i64(ptr align 8 %ref.tmp, ptr addrspace(4) align 8 %MIndex.i, i64 24, i1 false)
- br label %cond.end
-
-cond.end: ; preds = %cond.false, %for.cond.i42
- store i8 123, ptr addrspace(4) %add.ptr5
- br label %for.cond.i46
-
-for.cond.i46: ; preds = %for.inc.i52, %cond.end
- %Len.0.i47 = phi i32 [ 1, %cond.end ], [ %Len.1.i, %for.inc.i52 ]
- %I.0.i48 = phi i32 [ 0, %cond.end ], [ %inc7.i, %for.inc.i52 ]
- %cmp.i49 = icmp ult i32 %I.0.i48, 3
- br i1 %cmp.i49, label %for.body.i50, label %exit
-
-for.body.i50: ; preds = %for.cond.i46
- %idxprom.i.i = zext nneg i32 %I.0.i48 to i64
- %arrayidx.i.i51 = getelementptr inbounds [3 x i64], ptr %ref.tmp, i64 0, i64 %idxprom.i.i
- %5 = load i64, ptr %arrayidx.i.i51, align 8
- %idx.ext.i = zext i32 %Len.0.i47 to i64
- %add.ptr.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr5, i64 %idx.ext.i
- br label %do.body.i.i.i
-
-do.body.i.i.i: ; preds = %do.body.i.i.i, %for.body.i50
- %Val.addr.0.i.i.i = phi i64 [ %5, %for.body.i50 ], [ %div.i.i.i, %do.body.i.i.i ]
- %NumDigits.0.i.i.i = phi i32 [ 0, %for.body.i50 ], [ %inc.i.i.i, %do.body.i.i.i ]
- %Val.addr.0.i.i.i.frozen = freeze i64 %Val.addr.0.i.i.i
- %div.i.i.i = udiv i64 %Val.addr.0.i.i.i.frozen, 10
- %6 = mul i64 %div.i.i.i, 10
- %rem.i.i.i.decomposed = sub i64 %Val.addr.0.i.i.i.frozen, %6
- %7 = trunc i64 %rem.i.i.i.decomposed to i8
- %retval.0.i.i.i.i = or disjoint i8 %7, 48
- %inc.i.i.i = add i32 %NumDigits.0.i.i.i, 1
- %idxprom.i.i.i = zext i32 %NumDigits.0.i.i.i to i64
- %arrayidx.i.i.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr.i, i64 %idxprom.i.i.i
- store i8 %retval.0.i.i.i.i, ptr addrspace(4) %arrayidx.i.i.i
- %tobool.not.i.i.i = icmp ult i64 %Val.addr.0.i.i.i, 10
- br i1 %tobool.not.i.i.i, label %while.cond.i.i.i, label %do.body.i.i.i, !llvm.loop !4
-
-while.cond.i.i.i: ; preds = %while.body.i.i.i, %do.body.i.i.i
- %J.0.i.i.i = phi i32 [ %inc.i54.i.i, %while.body.i.i.i ], [ 0, %do.body.i.i.i ]
- %I.0.in.i.i.i = phi i32 [ %I.0.i.i.i, %while.body.i.i.i ], [ %inc.i.i.i, %do.body.i.i.i ]
- %I.0.i.i.i = add i32 %I.0.in.i.i.i, -1
- %cmp.i.i.i = icmp sgt i32 %I.0.i.i.i, %J.0.i.i.i
- br i1 %cmp.i.i.i, label %while.body.i.i.i, label %enable.exit
-
-while.body.i.i.i: ; preds = %while.cond.i.i.i
- %idxprom.i52.i.i = sext i32 %I.0.i.i.i to i64
- %arrayidx.i53.i.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr.i, i64 %idxprom.i52.i.i
- %8 = load i8, ptr addrspace(4) %arrayidx.i53.i.i
- %idxprom1.i.i.i = zext nneg i32 %J.0.i.i.i to i64
- %arrayidx2.i.i.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr.i, i64 %idxprom1.i.i.i
- %9 = load i8, ptr addrspace(4) %arrayidx2.i.i.i
- store i8 %9, ptr addrspace(4) %arrayidx.i53.i.i
- store i8 %8, ptr addrspace(4) %arrayidx2.i.i.i
- %inc.i54.i.i = add nuw nsw i32 %J.0.i.i.i, 1
- br label %while.cond.i.i.i, !llvm.loop !5
-
-enable.exit: ; preds = %while.cond.i.i.i
- %add.i = add i32 %Len.0.i47, %inc.i.i.i
- %cmp2.not.i = icmp eq i32 %I.0.i48, 2
- br i1 %cmp2.not.i, label %for.inc.i52, label %if.then.i
-
-if.then.i: ; preds = %enable.exit
- %idx.ext3.i = zext i32 %add.i to i64
- %add.ptr4.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr5, i64 %idx.ext3.i
- br label %for.cond.i.i
-
-for.cond.i.i: ; preds = %for.inc.i.i, %if.then.i
- %Len.0.i.i = phi i32 [ 0, %if.then.i ], [ %inc.i.i, %for.inc.i.i ]
- %idxprom.i24.i = zext i32 %Len.0.i.i to i64
- %arrayidx.i25.i = getelementptr inbounds i8, ptr addrspace(1) @.str.6, i64 %idxprom.i24.i
- %10 = load i8, ptr addrspace(1) %arrayidx.i25.i
- %cmp.not.i.i = icmp eq i8 %10, 0
- br i1 %cmp.not.i.i, label %for.cond1.i.i, label %for.inc.i.i
-
-for.inc.i.i: ; preds = %for.cond.i.i
- %inc.i.i = add i32 %Len.0.i.i, 1
- br label %for.cond.i.i, !llvm.loop !1
-
-for.cond1.i.i: ; preds = %for.body3.i.i, %for.cond.i.i
- %I.0.i.i = phi i32 [ %inc9.i.i, %for.body3.i.i ], [ 0, %for.cond.i.i ]
- %cmp2.i.i = icmp ult i32 %I.0.i.i, %Len.0.i.i
- br i1 %cmp2.i.i, label %for.body3.i.i, label %append.exit
-
-for.body3.i.i: ; preds = %for.cond1.i.i
- %idxprom4.i.i = zext i32 %I.0.i.i to i64
- %arrayidx5.i.i = getelementptr inbounds i8, ptr addrspace(1) @.str.6, i64 %idxprom4.i.i
- %11 = load i8, ptr addrspace(1) %arrayidx5.i.i
- %arrayidx7.i.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr4.i, i64 %idxprom4.i.i
- store i8 %11, ptr addrspace(4) %arrayidx7.i.i
- %inc9.i.i = add nuw i32 %I.0.i.i, 1
- br label %for.cond1.i.i, !llvm.loop !2
-
-append.exit: ; preds = %for.cond1.i.i
- %add6.i = add i32 %add.i, %Len.0.i.i
- br label %for.inc.i52
-
-for.inc.i52: ; preds = %append.exit, %enable.exit
- %Len.1.i = phi i32 [ %add6.i, %append.exit ], [ %add.i, %enable.exit ]
- %inc7.i = add nuw nsw i32 %I.0.i48, 1
- br label %for.cond.i46, !llvm.loop !6
-
-exit: ; preds = %for.cond.i46
- %inc8.i = add i32 %Len.0.i47, 1
- %idxprom9.i = zext i32 %Len.0.i47 to i64
- %arrayidx10.i = getelementptr inbounds i8, ptr addrspace(4) %add.ptr5, i64 %idxprom9.i
- store i8 125, ptr addrspace(4) %arrayidx10.i
- %add9 = add i32 %add3, %inc8.i
- %inc = add nuw nsw i32 %I.0, 1
- br label %for.cond, !llvm.loop !7
-}
-
-declare void @llvm.memset.p0.i64(ptr nocapture writeonly, i8, i64, i1 immarg)
-declare void @llvm.memcpy.p0.p4.i64(ptr noalias nocapture writeonly, ptr addrspace(4) noalias nocapture readonly, i64, i1 immarg)
-
-!0 = !{!"llvm.loop.mustprogress"}
-!1 = distinct !{!1, !0}
-!2 = distinct !{!2, !0}
-!3 = distinct !{!3, !0}
-!4 = distinct !{!4, !0}
-!5 = distinct !{!5, !0}
-!6 = distinct !{!6, !0}
-!7 = distinct !{!7, !0}
More information about the llvm-commits
mailing list