From c0db47487cd1bc5cd1fd39068d4c2838138b27d3 Mon Sep 17 00:00:00 2001 From: Ofek Date: Mon, 27 Nov 2023 17:33:03 +0200 Subject: [PATCH] Fix #5784 (#5793) Fix the name of the entry block in an IR control flow graph. --- lib/cfg/cfg-parsers/llvm-ir.ts | 16 ++++++++++------ test/cfg-cases/cfg-llvmir.invoke.json | 8 ++++---- test/cfg-cases/cfg-llvmir.loop.json | 6 +++--- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/lib/cfg/cfg-parsers/llvm-ir.ts b/lib/cfg/cfg-parsers/llvm-ir.ts index 9dbb93a29a5..00c630dbf0a 100644 --- a/lib/cfg/cfg-parsers/llvm-ir.ts +++ b/lib/cfg/cfg-parsers/llvm-ir.ts @@ -27,6 +27,7 @@ import {BaseInstructionSetInfo} from '../instruction-sets/base.js'; import {assert, unwrap} from '../../assert.js'; export type BBRange = { + namePrefix: string; // used to encode the function name in the first block nameId: string; start: number; end: number; @@ -79,29 +80,32 @@ export class LlvmIrCfgParser extends BaseCFGParser { const result: BBRange[] = []; let i = fn.start + 1; let bbStart = i; - let currentName = fnName; + let currentName: string = ''; + let namePrefix: string = fnName + '\n\n'; while (i < fn.end) { const match = code[i].text.match(this.labelRe); if (match) { + const label = match[1]; if (bbStart === i) { - // for -emit-llvm the first basic block doesn't have a label, for the ir viewer it does though assert(result.length === 0); - bbStart = i + 1; + currentName = label; } else { - const label = match[1]; // start is the fn / label define, end is exclusive result.push({ + namePrefix: namePrefix, nameId: currentName, start: bbStart, end: i, }); currentName = label; - bbStart = i + 1; + namePrefix = ''; } + bbStart = i + 1; } i++; } result.push({ + namePrefix: '', nameId: currentName, start: bbStart, end: i, @@ -118,7 +122,7 @@ export class LlvmIrCfgParser extends BaseCFGParser { } return { id: e.nameId, - label: `${e.nameId}${e.nameId.includes(':') ? '' : ':'}\n${this.concatInstructions( + label: `${e.namePrefix}${e.nameId}${e.nameId.includes(':') ? '' : ':'}\n${this.concatInstructions( asms, e.start, end, diff --git a/test/cfg-cases/cfg-llvmir.invoke.json b/test/cfg-cases/cfg-llvmir.invoke.json index 0ac2fb5e69c..8e115dca0aa 100644 --- a/test/cfg-cases/cfg-llvmir.invoke.json +++ b/test/cfg-cases/cfg-llvmir.invoke.json @@ -304,8 +304,8 @@ "f(int)(i32 noundef %n) personality i8* bitcast (i32 ": { "nodes": [ { - "id": "f(int)(i32 noundef %n) personality i8* bitcast (i32 ", - "label": "f(int)(i32 noundef %n) personality i8* bitcast (i32 :\n %retval = alloca i32, align 4\n %n.addr = alloca i32, align 4\n %a = alloca i32, align 4\n %exn.slot = alloca i8*, align 8\n %ehselector.slot = alloca i32, align 4\n store i32 %n, i32* %n.addr, align 4\n %0 = load i32, i32* %n.addr, align 4\n %call = invoke noundef i32 @g(int)(i32 noundef %0)\n to label %invoke.cont unwind label %lpad" + "id": "entry", + "label": "f(int)(i32 noundef %n) personality i8* bitcast (i32 \n\nentry:\n %retval = alloca i32, align 4\n %n.addr = alloca i32, align 4\n %a = alloca i32, align 4\n %exn.slot = alloca i8*, align 8\n %ehselector.slot = alloca i32, align 4\n store i32 %n, i32* %n.addr, align 4\n %0 = load i32, i32* %n.addr, align 4\n %call = invoke noundef i32 @g(int)(i32 noundef %0)\n to label %invoke.cont unwind label %lpad" }, { "id": "invoke.cont", @@ -330,13 +330,13 @@ ], "edges": [ { - "from": "f(int)(i32 noundef %n) personality i8* bitcast (i32 ", + "from": "entry", "to": "invoke.cont", "arrows": "to", "color": "green" }, { - "from": "f(int)(i32 noundef %n) personality i8* bitcast (i32 ", + "from": "entry", "to": "lpad", "arrows": "to", "color": "grey" diff --git a/test/cfg-cases/cfg-llvmir.loop.json b/test/cfg-cases/cfg-llvmir.loop.json index 0bb0edfc420..e6ac8e799ef 100644 --- a/test/cfg-cases/cfg-llvmir.loop.json +++ b/test/cfg-cases/cfg-llvmir.loop.json @@ -295,8 +295,8 @@ "foo(int*, int*, int)": { "nodes": [ { - "id": "foo(int*, int*, int)", - "label": "foo(int*, int*, int):\n %a.addr = alloca i32*, align 8\n %b.addr = alloca i32*, align 8\n %size.addr = alloca i32, align 4\n %i = alloca i32, align 4\n store i32* %a, i32** %a.addr, align 8\n store i32* %b, i32** %b.addr, align 8\n store i32 %size, i32* %size.addr, align 4\n store i32 0, i32* %i, align 4\n br label %for.cond" + "id": "entry", + "label": "foo(int*, int*, int)\n\nentry:\n %a.addr = alloca i32*, align 8\n %b.addr = alloca i32*, align 8\n %size.addr = alloca i32, align 4\n %i = alloca i32, align 4\n store i32* %a, i32** %a.addr, align 8\n store i32* %b, i32** %b.addr, align 8\n store i32 %size, i32* %size.addr, align 4\n store i32 0, i32* %i, align 4\n br label %for.cond" }, { "id": "for.cond", @@ -317,7 +317,7 @@ ], "edges": [ { - "from": "foo(int*, int*, int)", + "from": "entry", "to": "for.cond", "arrows": "to", "color": "blue"