From ef706af0d4f3f8fdbbf890396fb933b29a600fe9 Mon Sep 17 00:00:00 2001 From: Artur Gainullin Date: Mon, 22 Mar 2021 10:49:39 -0700 Subject: [PATCH] [SYCL] Check debug information integrity in the LowerWGScope pass * Add tests for debug info integrity * Fix pass to skip debug intrinsics when processing the instructions. --- llvm/lib/SYCLLowerIR/LowerWGScope.cpp | 3 +- llvm/test/SYCLLowerIR/hier_par_debug1.ll | 41 ++++++++++++ llvm/test/SYCLLowerIR/hier_par_debug2.ll | 80 ++++++++++++++++++++++++ llvm/test/SYCLLowerIR/hier_par_debug3.ll | 55 ++++++++++++++++ 4 files changed, 178 insertions(+), 1 deletion(-) create mode 100644 llvm/test/SYCLLowerIR/hier_par_debug1.ll create mode 100644 llvm/test/SYCLLowerIR/hier_par_debug2.ll create mode 100644 llvm/test/SYCLLowerIR/hier_par_debug3.ll diff --git a/llvm/lib/SYCLLowerIR/LowerWGScope.cpp b/llvm/lib/SYCLLowerIR/LowerWGScope.cpp index ab88b5bb58c22..5cd02b11b15d4 100644 --- a/llvm/lib/SYCLLowerIR/LowerWGScope.cpp +++ b/llvm/lib/SYCLLowerIR/LowerWGScope.cpp @@ -786,7 +786,8 @@ PreservedAnalyses SYCLLowerWGScopePass::run(Function &F, Instruction *I = BB.getFirstNonPHI(); for (; I->getOpcode() == Instruction::Alloca || - I->getOpcode() == Instruction::AddrSpaceCast; + I->getOpcode() == Instruction::AddrSpaceCast || + I->isDebugOrPseudoInst(); I = I->getNextNode()) { auto *AllocaI = dyn_cast(I); // Allocas marked with "work_item_scope" are those originating from diff --git a/llvm/test/SYCLLowerIR/hier_par_debug1.ll b/llvm/test/SYCLLowerIR/hier_par_debug1.ll new file mode 100644 index 0000000000000..f589d75d7431c --- /dev/null +++ b/llvm/test/SYCLLowerIR/hier_par_debug1.ll @@ -0,0 +1,41 @@ +; RUN: opt < %s -debugify -LowerWGScope -S | FileCheck %s + +; Check that debug info is not lost after the LowerWGScope pass. +; Typical case of pfwg + pfwi usage. + +%struct.bar = type { i8 } +%struct.zot = type { %struct.widget, %struct.widget, %struct.widget, %struct.foo } +%struct.widget = type { %struct.barney } +%struct.barney = type { [3 x i64] } +%struct.foo = type { %struct.barney } +%struct.foo.0 = type { i8 } + +define internal spir_func void @wibble(%struct.bar addrspace(4)* %arg, %struct.zot* byval(%struct.zot) align 8 %arg1) align 2 !work_group_scope !0 { +; CHECK-LABEL: define {{[^@]+}}@wibble +; CHECK-SAME: (%struct.bar addrspace(4)* [[ARG:%.*]], %struct.zot* byval(%struct.zot) align 8 [[ARG1:%.*]]) +bb: + %tmp = alloca %struct.bar addrspace(4)*, align 8 +; CHECK: [[TMP:%.*]] = alloca %struct.bar addrspace(4)*, align 8 +; CHECK: call void @llvm.dbg.value(metadata %struct.bar addrspace(4)** [[TMP]], [[META9:metadata !.*]], metadata !DIExpression()) + %tmp1 = alloca %struct.foo.0, align 1 +; CHECK: [[TMP1:%.*]] = alloca %struct.foo.0, align 1 +; CHECK: call void @llvm.dbg.value(metadata %struct.foo.0* [[TMP1]], [[META11:metadata !.*]], metadata !DIExpression()) + store %struct.bar addrspace(4)* %arg, %struct.bar addrspace(4)** %tmp, align 8 + %tmp3 = load %struct.bar addrspace(4)*, %struct.bar addrspace(4)** %tmp, align 8 +; CHECK: [[TMP3:%.*]] = load %struct.bar addrspace(4)*, %struct.bar addrspace(4)** [[TMP]], align 8 +; CHECK: call void @llvm.dbg.value(metadata %struct.bar addrspace(4)* [[TMP3]], [[META12:metadata !.*]], metadata !DIExpression()) + %tmp4 = addrspacecast %struct.zot* %arg1 to %struct.zot addrspace(4)* +; CHECK: [[TMP4:%.*]] = addrspacecast %struct.zot* [[ARG1]] to %struct.zot addrspace(4)* +; CHECK: call void @llvm.dbg.value(metadata %struct.zot addrspace(4)* [[TMP4]], [[META13:metadata !.*]], metadata !DIExpression()) + call spir_func void @bar(%struct.zot addrspace(4)* %tmp4, %struct.foo.0* byval(%struct.foo.0) align 1 %tmp1) + ret void +} + +define internal spir_func void @bar(%struct.zot addrspace(4)* %arg, %struct.foo.0* byval(%struct.foo.0) align 1 %arg1) align 2 !work_item_scope !0 !parallel_for_work_item !0 { +; CHECK-LABEL: define {{[^@]+}}@bar +; CHECK: call void @llvm.dbg.value(metadata i32 0, [[META23:metadata !.*]], metadata !DIExpression()) +bb: + ret void +} + +!0 = !{} diff --git a/llvm/test/SYCLLowerIR/hier_par_debug2.ll b/llvm/test/SYCLLowerIR/hier_par_debug2.ll new file mode 100644 index 0000000000000..ef8ed48983dae --- /dev/null +++ b/llvm/test/SYCLLowerIR/hier_par_debug2.ll @@ -0,0 +1,80 @@ +; RUN: opt < %s -debugify -LowerWGScope -S | FileCheck %s +; +; Check that debug info is not lost after LowerWGScope pass. +; Case with private_mem usage. + +%struct.snork = type { i8 } +%struct.wobble = type { %struct.spam, %struct.spam, %struct.spam, %struct.snork.0 } +%struct.spam = type { %struct.foo } +%struct.foo = type { [2 x i64] } +%struct.snork.0 = type { %struct.foo } +%struct.ham = type { %struct.pluto } +%struct.pluto = type { i32, i32 } +%struct.wibble = type { %struct.ham addrspace(4)* } + +define internal spir_func void @wibble(%struct.snork addrspace(4)* dereferenceable_or_null(1) %arg, %struct.wobble* byval(%struct.wobble) align 8 %arg1) align 2 !work_group_scope !0 { +; CHECK-LABEL: define {{[^@]+}}@wibble +; CHECK-SAME: (%struct.snork addrspace(4)* dereferenceable_or_null(1) [[ARG:%.*]], %struct.wobble* byval(%struct.wobble) align 8 [[ARG1:%.*]]) +; +bb: + %tmp = alloca %struct.snork addrspace(4)*, align 8 +; CHECK: [[TMP:%.*]] = alloca %struct.snork addrspace(4)*, align 8 +; CHECK: call void @llvm.dbg.value(metadata %struct.snork addrspace(4)** [[TMP]], [[META9:metadata !.*]], metadata !DIExpression()) + %tmp2 = addrspacecast %struct.snork addrspace(4)** %tmp to %struct.snork addrspace(4)* addrspace(4)* +; CHECK: [[TMP2:%.*]] = addrspacecast %struct.snork addrspace(4)** [[TMP]] to %struct.snork addrspace(4)* addrspace(4)* +; CHECK: call void @llvm.dbg.value(metadata %struct.snork addrspace(4)* addrspace(4)* [[TMP2]], [[META11:metadata !.*]], metadata !DIExpression()) + %tmp3 = alloca %struct.ham, align 4, !work_item_scope !0 +; CHECK: [[TMP3:%.*]] = alloca %struct.ham, align 4, [[DBG24:!dbg !.*]], !work_item_scope !2 +; CHECK: call void @llvm.dbg.value(metadata %struct.ham* [[TMP3]], [[META12:metadata !.*]], metadata !DIExpression()) + %tmp4 = addrspacecast %struct.ham* %tmp3 to %struct.ham addrspace(4)* +; CHECK: [[TMP4:%.*]] = addrspacecast %struct.ham* [[TMP3]] to %struct.ham addrspace(4)* +; CHECK: call void @llvm.dbg.value(metadata %struct.ham addrspace(4)* [[TMP4]], [[META13:metadata !.*]], metadata !DIExpression()) + %tmp5 = alloca %struct.spam, align 8 +; CHECK: [[TMP5:%.*]] = alloca %struct.spam, align 8 +; CHECK: call void @llvm.dbg.value(metadata %struct.spam* [[TMP5]], [[META14:metadata !.*]], metadata !DIExpression()) + %tmp6 = addrspacecast %struct.spam* %tmp5 to %struct.spam addrspace(4)* +; CHECK: [[TMP6:%.*]] = addrspacecast %struct.spam* [[TMP5]] to %struct.spam addrspace(4)* +; CHECK: call void @llvm.dbg.value(metadata %struct.spam addrspace(4)* [[TMP6]], [[META15:metadata !.*]], metadata !DIExpression()) + %tmp7 = alloca %struct.wibble, align 8 +; CHECK: [[TMP7:%.*]] = alloca %struct.wibble, align 8 +; CHECK: call void @llvm.dbg.value(metadata %struct.wibble* [[TMP7]], [[META16:metadata !.*]], metadata !DIExpression()) + %tmp8 = addrspacecast %struct.wibble* %tmp7 to %struct.wibble addrspace(4)* +; CHECK: [[TMP8:%.*]] = addrspacecast %struct.wibble* [[TMP7]] to %struct.wibble addrspace(4)* +; CHECK: call void @llvm.dbg.value(metadata %struct.wibble addrspace(4)* [[TMP8]], [[META17:metadata !.*]], metadata !DIExpression()) + store %struct.snork addrspace(4)* %arg, %struct.snork addrspace(4)* addrspace(4)* %tmp2, align 8 + %tmp9 = addrspacecast %struct.wobble* %arg1 to %struct.wobble addrspace(4)* +; CHECK: [[TMP9:%.*]] = addrspacecast %struct.wobble* [[ARG1]] to %struct.wobble addrspace(4)* +; CHECK: call void @llvm.dbg.value(metadata %struct.wobble addrspace(4)* [[TMP9]], [[META18:metadata !.*]], metadata !DIExpression()) + call spir_func void @eggs(%struct.ham addrspace(4)* dereferenceable_or_null(8) %tmp4, %struct.wobble addrspace(4)* align 8 dereferenceable(64) %tmp9) + call spir_func void @snork(%struct.spam addrspace(4)* dereferenceable_or_null(16) %tmp6, i64 7, i64 3) + %tmp10 = getelementptr inbounds %struct.wibble, %struct.wibble addrspace(4)* %tmp8, i32 0, i32 0 +; CHECK: [[TMP10:%.*]] = getelementptr inbounds %struct.wibble, %struct.wibble addrspace(4)* [[TMP8]], i32 0, i32 0 +; CHECK: call void @llvm.dbg.value(metadata %struct.ham addrspace(4)* addrspace(4)* [[TMP10]], [[META19:metadata !.*]], metadata !DIExpression()) + store %struct.ham addrspace(4)* %tmp4, %struct.ham addrspace(4)* addrspace(4)* %tmp10, align 8 + %tmp11 = addrspacecast %struct.spam addrspace(4)* %tmp6 to %struct.spam* +; CHECK: [[TMP11:%.*]] = addrspacecast %struct.spam addrspace(4)* [[TMP6]] to %struct.spam* +; CHECK: call void @llvm.dbg.value(metadata %struct.spam* [[TMP11]], [[META20:metadata !.*]], metadata !DIExpression()) + %tmp12 = addrspacecast %struct.wibble addrspace(4)* %tmp8 to %struct.wibble* + call spir_func void @wombat(%struct.wobble addrspace(4)* dereferenceable_or_null(64) %tmp9, %struct.spam* byval(%struct.spam) align 8 %tmp11, %struct.wibble* byval(%struct.wibble) align 8 %tmp12) +; CHECK: [[TMP12:%.*]] = addrspacecast %struct.wibble addrspace(4)* [[TMP8]] to %struct.wibble* +; CHECK: call void @llvm.dbg.value(metadata %struct.wibble* [[TMP12]], [[META21:metadata !.*]], metadata !DIExpression()) + ret void +} + +define linkonce_odr dso_local spir_func void @eggs(%struct.ham addrspace(4)* dereferenceable_or_null(8) %arg, %struct.wobble addrspace(4)* align 8 dereferenceable(64) %arg1) align 2 { +bb: + ret void +} + +define internal spir_func void @wombat(%struct.wobble addrspace(4)* dereferenceable_or_null(64) %arg, %struct.spam* byval(%struct.spam) align 8 %arg1, %struct.wibble* byval(%struct.wibble) align 8 %arg2) align 2 !work_item_scope !0 !parallel_for_work_item !0 { +bb: +; CHECK: call void @llvm.dbg.value(metadata i32 0, [[META42:metadata !.*]], metadata !DIExpression()) + ret void +} + +define linkonce_odr dso_local spir_func void @snork(%struct.spam addrspace(4)* dereferenceable_or_null(16) %arg, i64 %arg1, i64 %arg2) align 2 { +bb: + ret void +} + +!0 = !{} diff --git a/llvm/test/SYCLLowerIR/hier_par_debug3.ll b/llvm/test/SYCLLowerIR/hier_par_debug3.ll new file mode 100644 index 0000000000000..803a133dbac57 --- /dev/null +++ b/llvm/test/SYCLLowerIR/hier_par_debug3.ll @@ -0,0 +1,55 @@ +; RUN: opt < %s -debugify -LowerWGScope -S | FileCheck %s +; +; Check that debug info is not lost after the LowerWGScope pass. +; Case with additional control flow in pfwg. + + +%struct.snork = type { i32 } +%struct.eggs = type { i8 } +%struct.snork.0 = type { %struct.widget, %struct.widget, %struct.widget, %struct.ham } +%struct.widget = type { %struct.wibble } +%struct.wibble = type { [3 x i64] } +%struct.ham = type { %struct.wibble } + +@global = internal addrspace(3) global [12 x %struct.snork] zeroinitializer, align 4 + +define internal spir_func void @spam(%struct.eggs addrspace(4)* %arg, %struct.snork.0* byval(%struct.snork.0) align 8 %arg1) align 2 !work_group_scope !0 { +; CHECK-LABEL: define {{[^@]+}}@spam +; CHECK-SAME: (%struct.eggs addrspace(4)* [[ARG:%.*]], %struct.snork.0* byval(%struct.snork.0) align 8 [[ARG1:%.*]]) +entry: + %tmp = alloca %struct.eggs addrspace(4)*, align 8 +; CHECK: [[TMP:%.*]] = alloca %struct.eggs addrspace(4)*, align 8 +; CHECK: call void @llvm.dbg.value(metadata %struct.eggs addrspace(4)** [[TMP]], [[META9:metadata !.*]], metadata !DIExpression()) + store %struct.eggs addrspace(4)* %arg, %struct.eggs addrspace(4)** %tmp, align 8 + %tmp2 = load %struct.eggs addrspace(4)*, %struct.eggs addrspace(4)** %tmp, align 8 +; CHECK: [[TMP2:%.*]] = load %struct.eggs addrspace(4)*, %struct.eggs addrspace(4)** [[TMP]], align 8 +; CHECK: call void @llvm.dbg.value(metadata %struct.eggs addrspace(4)* [[TMP2]], [[META11:metadata !.*]], metadata !DIExpression()) + br label %arrayctor.loop +arrayctor.loop: ; preds = %arrayctor.loop, %entry + %arrayctor.cur = phi %struct.snork addrspace(4)* [ getelementptr inbounds ([12 x %struct.snork], [12 x %struct.snork] addrspace(4)* addrspacecast ([12 x %struct.snork] addrspace(3)* @global to [12 x %struct.snork] addrspace(4)*), i32 0, i32 0), %entry ], [ %arrayctor.next, %arrayctor.loop ] +; CHECK: [[ARRAYCTOR_CUR:%.*]] = phi [[STRUCT_SNORK:%.*]] addrspace(4)* [ getelementptr inbounds ([12 x %struct.snork], [12 x %struct.snork] addrspace(4)* addrspacecast ([12 x %struct.snork] addrspace(3)* @global to [12 x %struct.snork] addrspace(4)*), i32 0, i32 0), [[ENTRY:%.*]] ], [ [[ARRAYCTOR_NEXT:%.*]], [[ARRAYCTOR_LOOP:%.*]] ] +; CHECK: call void @llvm.dbg.value(metadata %struct.snork addrspace(4)* [[ARRAYCTOR_CUR]], [[META12:metadata !.*]], metadata !DIExpression()) + call spir_func void @bar(%struct.snork addrspace(4)* %arrayctor.cur) + %arrayctor.next = getelementptr inbounds %struct.snork, %struct.snork addrspace(4)* %arrayctor.cur, i64 1 +; CHECK: [[GEP_VAL:%.*]] = getelementptr inbounds %struct.snork, %struct.snork addrspace(4)* [[ARRAYCTOR_CUR]], i64 1 +; CHECK: call void @llvm.dbg.value(metadata %struct.snork addrspace(4)* [[GEP_VAL]], [[META13:metadata !.*]], metadata !DIExpression()) + %arrayctor.done = icmp eq %struct.snork addrspace(4)* %arrayctor.next, getelementptr inbounds (%struct.snork, %struct.snork addrspace(4)* getelementptr inbounds ([12 x %struct.snork], [12 x %struct.snork] addrspace(4)* addrspacecast ([12 x %struct.snork] addrspace(3)* @global to [12 x %struct.snork] addrspace(4)*), i32 0, i32 0), i64 12) +; CHECK: [[ARRAYCTOR_DONE:%.*]] = icmp eq %struct.snork addrspace(4)* [[WG_VAL_ARRAYCTOR_NEXT:%.*]], getelementptr inbounds (%struct.snork, %struct.snork addrspace(4)* getelementptr inbounds ([12 x %struct.snork], [12 x %struct.snork] addrspace(4)* addrspacecast ([12 x %struct.snork] addrspace(3)* @global to [12 x %struct.snork] addrspace(4)*), i32 0, i32 0), i64 12) +; CHECK: call void @llvm.dbg.value(metadata i1 [[ARRAYCTOR_DONE]], [[META14:metadata !.*]], metadata !DIExpression()) + br i1 %arrayctor.done, label %arrayctor.cont, label %arrayctor.loop + +arrayctor.cont: ; preds = %arrayctor.loop + ret void +} + +define linkonce_odr dso_local spir_func void @bar(%struct.snork addrspace(4)* %arg) unnamed_addr align 2 { +bb: + %tmp = alloca %struct.snork addrspace(4)*, align 8 + store %struct.snork addrspace(4)* %arg, %struct.snork addrspace(4)** %tmp, align 8 + %tmp1 = load %struct.snork addrspace(4)*, %struct.snork addrspace(4)** %tmp, align 8 + %tmp2 = getelementptr inbounds %struct.snork, %struct.snork addrspace(4)* %tmp1, i32 0, i32 0 + store i32 0, i32 addrspace(4)* %tmp2, align 4 + ret void +} + +!0 = !{}