LLVM's pass ordering chokes on zero-cost abstractions. (original) (raw)

The latest example of this I've seen was posted by @Veedrac to Hacker News (try on playground):

static table: [i32; 4] = [0; 4];

pub fn exists_in_table(v: i32) -> bool { for &x in table.iter() { if x == v { return true; } }

false

}

After -C opt-level=3 the ~600 lines of unoptimized IR turn into this (note br i1 false):

; playground::exists_in_table ; Function Attrs: nounwind uwtable define zeroext i1 @_ZN10playground15exists_in_table17h0a39bf7934b9be37E(i32) unnamed_addr #0 { start: br label %bb3

bb3: ; preds = %start br i1 false, label %bb9, label %bb6

bb6: ; preds = %bb3 %1 = icmp eq i32 %0, 0 br i1 %1, label %bb9, label %bb3.1

bb9: ; preds = %bb6.4, %bb3.4, %bb6.3, %bb3.3, %bb6.2, %bb3.2, %bb6.1, %bb3.1, %bb3, %bb6 %_0.0 = phi i1 [ true, %bb6 ], [ false, %bb3 ], [ false, %bb3.1 ], [ true, %bb6.1 ], [ false, %bb3.2 ], [ true, %bb6.2 ], [ false, %bb3.3 ], [ true, %bb6.3 ], [ false, %bb3.4 ], [ true, %bb6.4 ] ret i1 %_0.0

bb3.1: ; preds = %bb6 br i1 false, label %bb9, label %bb6.1

bb6.1: ; preds = %bb3.1 %2 = icmp eq i32 %0, 0 br i1 %2, label %bb9, label %bb3.2

bb3.2: ; preds = %bb6.1 br i1 false, label %bb9, label %bb6.2

bb6.2: ; preds = %bb3.2 %3 = icmp eq i32 %0, 0 br i1 %3, label %bb9, label %bb3.3

bb3.3: ; preds = %bb6.2 br i1 false, label %bb9, label %bb6.3

bb6.3: ; preds = %bb3.3 %4 = icmp eq i32 %0, 0 br i1 %4, label %bb9, label %bb3.4

bb3.4: ; preds = %bb6.3 br i1 true, label %bb9, label %bb6.4

bb6.4: ; preds = %bb3.4 br label %bb9 }