Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

while with a comptime false condition should work like static if #1705

Open
andrewrk opened this issue Nov 7, 2018 · 0 comments
Open

while with a comptime false condition should work like static if #1705

andrewrk opened this issue Nov 7, 2018 · 0 comments
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Nov 7, 2018

export fn entry() void {
    const c = false;
    const x: error!i32 = error.Failure;
    var z = while (x) |a| {
        if (c) break a;
    } else |_| i32(3);
}

This generates analyzed Zig IR:

fn entry() { // (analyzed)
Entry_0:
    #3  | void        | - | const c = false // comptime = false
    #14 | void        | - | const x: error!i32 = error!i32(error.Failure) // comptime = false
    #18 | noreturn    | - | goto $WhileCond_17
WhileCond_17:
    #23 | noreturn    | - | goto $WhileElse_22
WhileElse_22:
    #25 | void        | - | var _anon = error.Failure // comptime = false
    #30 | noreturn    | - | goto $WhileEnd_29
WhileEnd_29:
    #31 | void        | - | var z = 3 // comptime = false
    #34 | noreturn    | - | return {}
}

which generates the llvm ir:

define void @entry() #2 !dbg !42 {
Entry:
  %c = alloca i1, align 1
  %x = alloca { i16, i32 }, align 4
  %_anon = alloca i16, align 2
  %z = alloca i32, align 4
  store i1 false, i1* %c, align 1, !dbg !59
  call void @llvm.dbg.declare(metadata i1* %c, metadata !46, metadata !DIExpression()), !dbg !59
  %0 = bitcast { i16, i32 }* %x to i8*, !dbg !60
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast ({ i16, i32 }* @0 to i8*), i64 8, i1 false), !dbg !60
  call void @llvm.dbg.declare(metadata { i16, i32 }* %x, metadata !49, metadata !DIExpression()), !dbg !60
  br label %WhileCond, !dbg !61

WhileCond:                                        ; preds = %Entry
  br label %WhileElse, !dbg !62

WhileElse:                                        ; preds = %WhileCond
  store i16 1, i16* %_anon, align 2, !dbg !63
  call void @llvm.dbg.declare(metadata i16* %_anon, metadata !56, metadata !DIExpression()), !dbg !65
  br label %WhileEnd, !dbg !61

WhileEnd:                                         ; preds = %WhileElse
  store i32 3, i32* %z, align 4, !dbg !66
  call void @llvm.dbg.declare(metadata i32* %z, metadata !58, metadata !DIExpression()), !dbg !66
  ret void, !dbg !67
}

Instead this should be equivalent to:

export fn entry() void {
    const c = false;
    const x: error!i32 = error.Failure;
    var z = if (x) |a| blk: {
        if (c) break :blk a;
    } else |_| i32(3);
}

which generates this zig ir:

fn entry() { // (analyzed)
Entry_0:
    #3  | void        | - | const c = false // comptime = false
    #14 | void        | - | const x: error!i32 = error!i32(error.Failure) // comptime = false
    #26 | void        | - | var z = 3 // comptime = false
    #29 | noreturn    | - | return {}
}

and this LLVM IR:

define void @entry() #2 !dbg !42 {
Entry:
  %c = alloca i1, align 1
  %x = alloca { i16, i32 }, align 4
  %z = alloca i32, align 4
  store i1 false, i1* %c, align 1, !dbg !58
  call void @llvm.dbg.declare(metadata i1* %c, metadata !46, metadata !DIExpression()), !dbg !58
  %0 = bitcast { i16, i32 }* %x to i8*, !dbg !59
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 4 %0, i8* align 4 bitcast ({ i16, i32 }* @0 to i8*), i64 8, i1 false), !dbg !59
  call void @llvm.dbg.declare(metadata { i16, i32 }* %x, metadata !49, metadata !DIExpression()), !dbg !59
  store i32 3, i32* %z, align 4, !dbg !60
  call void @llvm.dbg.declare(metadata i32* %z, metadata !56, metadata !DIExpression()), !dbg !60
  ret void, !dbg !61
}

Note that with #287 the expected LLVM IR is even slimmer:

define void @entry() #2 !dbg !42 {
Entry:
  %z = alloca i32, align 4
  call void @llvm.dbg.declare(metadata i1* @1, metadata !46, metadata !DIExpression()), !dbg !58
  call void @llvm.dbg.declare(metadata { i16, i32 }* @3, metadata !49, metadata !DIExpression()), !dbg !59
  store i32 3, i32* %z, align 4, !dbg !60
  call void @llvm.dbg.declare(metadata i32* %z, metadata !56, metadata !DIExpression()), !dbg !60
  ret void, !dbg !61
}
@andrewrk andrewrk added proposal This issue suggests modifications. If it also has the "accepted" label then it is planned. accepted This proposal is planned. labels Nov 7, 2018
@andrewrk andrewrk added this to the 0.5.0 milestone Nov 7, 2018
@andrewrk andrewrk modified the milestones: 0.5.0, 0.6.0 Jul 3, 2019
@andrewrk andrewrk modified the milestones: 0.6.0, 0.7.0 Feb 10, 2020
@andrewrk andrewrk modified the milestones: 0.7.0, 0.8.0 Oct 9, 2020
@andrewrk andrewrk modified the milestones: 0.8.0, 0.9.0 May 19, 2021
@andrewrk andrewrk modified the milestones: 0.9.0, 0.10.0 Nov 20, 2021
@andrewrk andrewrk modified the milestones: 0.10.0, 0.11.0 Apr 16, 2022
@andrewrk andrewrk modified the milestones: 0.11.0, 0.12.0 Apr 9, 2023
@andrewrk andrewrk modified the milestones: 0.13.0, 0.12.0 Jun 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
accepted This proposal is planned. proposal This issue suggests modifications. If it also has the "accepted" label then it is planned.
Projects
None yet
Development

No branches or pull requests

1 participant