[llvm-dev] is there something obviously wrong with my llvm ir code? why is it generating a trap?
Andrew Kelley via llvm-dev
llvm-dev at lists.llvm.org
Sun Jul 21 20:49:57 PDT 2019
Here's the frontend code:
var x: i32 = 1;
export fn entry() void {
const p = async simpleAsyncFn(2);
assert(x == 3);
resume p;
assert(x == 5); // this is getting replace with a trap()
}
fn simpleAsyncFn(delta: i32) void {
x += delta;
suspend;
x += delta;
}
Here's the generated LLVM IR:
; ModuleID = 'test'
source_filename = "test"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%"[]u8" = type { i8*, i64 }
%builtin.StackTrace = type { i64, %"[]usize" }
%"[]usize" = type { i64*, i64 }
%"@Frame(simpleAsyncFn)" = type { i64, i32 }
@x = internal unnamed_addr global i32 1, align 4
@assert = internal unnamed_addr constant void (i1)* @std.debug.assert,
align 8
; Function Attrs: nobuiltin nounwind
define internal fastcc void @std.debug.assert(i1) unnamed_addr #0 {
Entry:
%ok = alloca i1, align 1
store i1 %0, i1* %ok, align 1
%1 = load i1, i1* %ok, align 1
%2 = icmp eq i1 %1, false
br i1 %2, label %Then, label %Else
Then: ; preds = %Entry
unreachable
Else: ; preds = %Entry
br label %EndIf
EndIf: ; preds = %Else
ret void
}
; Function Attrs: nobuiltin nounwind
define void @entry() #0 {
Entry:
%p = alloca %"@Frame(simpleAsyncFn)", align 8
%0 = getelementptr inbounds %"@Frame(simpleAsyncFn)",
%"@Frame(simpleAsyncFn)"* %p, i32 0, i32 0
store i64 0, i64* %0
%1 = getelementptr inbounds %"@Frame(simpleAsyncFn)",
%"@Frame(simpleAsyncFn)"* %p, i32 0, i32 1
store i32 2, i32* %1
%2 = call fastcc i64 @simpleAsyncFn(%"@Frame(simpleAsyncFn)"* %p)
%3 = load i32, i32* @x, align 4
%4 = icmp eq i32 %3, 3
call fastcc void @std.debug.assert(i1 %4)
%5 = call i64 @simpleAsyncFn(%"@Frame(simpleAsyncFn)"* %p)
%6 = load i32, i32* @x, align 4
%7 = icmp eq i32 %6, 5
call fastcc void @std.debug.assert(i1 %7)
ret void
}
; Function Attrs: nobuiltin nounwind
define internal fastcc i64 @simpleAsyncFn(%"@Frame(simpleAsyncFn)"*
nonnull align 8) unnamed_addr #0 {
AsyncSwitch:
%1 = getelementptr inbounds %"@Frame(simpleAsyncFn)",
%"@Frame(simpleAsyncFn)"* %0, i32 0, i32 1
%2 = getelementptr inbounds %"@Frame(simpleAsyncFn)",
%"@Frame(simpleAsyncFn)"* %0, i32 0, i32 0
%3 = load i64, i64* %2
switch i64 %3, label %BadResume [
i64 0, label %Entry
i64 1, label %GetSize
i64 2, label %Resume
]
Entry: ; preds = %AsyncSwitch
%4 = load i32, i32* @x, align 4
%5 = load i32, i32* %1, align 4
%6 = add nsw i32 %4, %5
store i32 %6, i32* @x, align 4
%7 = getelementptr inbounds %"@Frame(simpleAsyncFn)",
%"@Frame(simpleAsyncFn)"* %0, i32 0, i32 0
store i64 2, i64* %7
ret i64 undef
Resume: ; preds = %AsyncSwitch
%8 = load i32, i32* @x, align 4
%9 = load i32, i32* %1, align 4
%10 = add nsw i32 %8, %9
store i32 %10, i32* @x, align 4
ret i64 undef
BadResume: ; preds = %AsyncSwitch
unreachable
GetSize: ; preds = %AsyncSwitch
ret i64 16
}
attributes #0 = { nobuiltin nounwind }
attributes #1 = { nobuiltin noreturn nounwind }
!llvm.module.flags = !{!0}
!llvm.dbg.cu = !{!1}
!0 = !{i32 2, !"Debug Info Version", i32 3}
!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer:
"zig 0.4.0", isOptimized: true, runtimeVersion: 0, emissionKind:
NoDebug, enums: !3)
!2 = !DIFile(filename: "test", directory: ".")
!3 = !{}
When I turn on optimizations, I get this (note the trap() at the end):
define void @entry() local_unnamed_addr #0 {
Entry:
%p = alloca %"@Frame(simpleAsyncFn)", align 8
%0 = getelementptr inbounds %"@Frame(simpleAsyncFn)",
%"@Frame(simpleAsyncFn)"* %p, i64 0, i32 0
store i64 0, i64* %0, align 8
%1 = getelementptr inbounds %"@Frame(simpleAsyncFn)",
%"@Frame(simpleAsyncFn)"* %p, i64 0, i32 1
store i32 2, i32* %1, align 8
call fastcc void @simpleAsyncFn(%"@Frame(simpleAsyncFn)"* %p)
tail call void @llvm.trap()
unreachable
}
This seems to indicate that the optimizer was able to prove that my
(second) assertion was incorrect. But I don't see how this is possible.
Does anyone else see it?
Thanks,
Andrew
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: OpenPGP digital signature
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190721/f5b4271f/attachment.sig>
More information about the llvm-dev
mailing list