-
Notifications
You must be signed in to change notification settings - Fork 15.3k
Open
Description
This Rust program:
use std::cell::Cell;
thread_local! {
pub static FOO: Cell<u32> = Cell::new(0xffff);
}
pub fn bar() -> u32 {
FOO.get() + FOO.get()
}results in (at least) a duplicate load + trunc:
First version:
%0 = load i32, ptr @"_ZN7example3FOO29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$3VAL17h49f9a1072bb59151E", align 4, !range !3, !noalias !4, !noundef !11
%trunc.i.i.i.i.i = trunc nuw i32 %0 to i1Second version:
%self3.val.pre.i.i = load i32, ptr getelementptr inbounds nuw (i8, ptr @"_ZN7example3FOO29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$3VAL17h49f9a1072bb59151E", i64 4), align 4
%1 = trunc nuw i32 %0 to i1At minimum it'd be great to eliminate the double trunc, but combining the two loads also seems worthwhile (it should be possible AFAICT to deduplicate those). That would avoid two TLS address lookups in the resulting IR and should allow for further simplification (e.g., dropping some branches).
define noundef i32 @_ZN7example3bar17h6628f733c3c7a49fE() unnamed_addr #0 personality ptr @rust_eh_personality {
start:
%0 = load i32, ptr @"_ZN7example3FOO29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$3VAL17h49f9a1072bb59151E", align 4, !range !3, !noalias !4, !noundef !11
%trunc.i.i.i.i.i = trunc nuw i32 %0 to i1
br i1 %trunc.i.i.i.i.i, label %"_ZN3std6thread5local17LocalKey$LT$T$GT$4with17h35c29327e034454aE.exit", label %"_ZN3std6thread5local17LocalKey$LT$T$GT$4with17h35c29327e034454aE.exit6.sink.split", !prof !12
"_ZN3std6thread5local17LocalKey$LT$T$GT$4with17h35c29327e034454aE.exit": ; preds = %start
%self3.val.pre.i.i = load i32, ptr getelementptr inbounds nuw (i8, ptr @"_ZN7example3FOO29_$u7b$$u7b$constant$u7d$$u7d$28_$u7b$$u7b$closure$u7d$$u7d$3VAL17h49f9a1072bb59151E", i64 4), align 4
%1 = trunc nuw i32 %0 to i1
...Godbolt: https://rust.godbolt.org/z/dPb4bPTTe