Rust: рдПрдХ рдмрд╛рд░ рдПрд▓рдПрд▓рд╡реАрдПрдо рджреНрд╡рд╛рд░рд╛ рдЙрдиреНрд╣реЗрдВ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рди рдХрд░рдиреЗ рдкрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдиреЛрдЕрд▓рд┐рдпрд╛ рдПрдиреЛрдЯреЗрд╢рди рдХреЛ рдлрд┐рд░ рд╕реЗ рд╕рдХреНрд╖рдо рдХрд░реЗрдВ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 6 рдЕрдХреНрддреВре░ 2018  ┬╖  33рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: rust-lang/rust

рдпрд╣ рд╕рдорд╕реНрдпрд╛ LLVM рдореЗрдВ рдПрдХ рдмрдЧ рдХреЗ рдХрд╛рд░рдг https://github.com/rust-lang/rust/pull/54639 рдореЗрдВ рдкреЗрд╢ рдХрд┐рдП рдЧрдП -Zmutable-alias=no рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреЛ рдкреВрд░реНрд╡рд╡рдд рдХрд░рдиреЗ рдХреЛ рдЯреНрд░реИрдХ рдХрд░рддреА рд╣реИред рд╕реАрд╕реА @nagisa

( рджреЗрдЬрд╛ рд╡реВ? )

A-LLVM A-codegen C-tracking-issue I-slow T-compiler

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдореИрдВрдиреЗ рдЗрд╕реЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╕реА рдЯреЗрд╕реНрдЯ рдХреЗрд╕ рдореЗрдВ рдШрдЯрд╛ рджрд┐рдпрд╛ (-O3 рдФрд░ -O0 рдкрд░ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ):

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

__attribute__((always_inline))
static inline void copy(int *restrict a, int *restrict b) {
    assert(a != b);
    *b = *a;
    *a = 7;
}

__attribute__((noinline))
void floppy(int mat[static 2], size_t idxs[static 3]) {
    for (int i = 0; i < 3; i++) {
        copy(&mat[i%2], &mat[idxs[i]]);
    }
}

int main() {
    int mat[3] = {10, 20};
    size_t idxs[3] = {1, 0, 1};
    floppy(mat, idxs);
    printf("%d %d\n", mat[0], mat[1]);
}

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдк restrict , noalias рдмрд░рд╛рдмрд░ C рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕рд╣реА рд╣реИред рдлрд┐рд░ рднреА, assert(a != b) рдЧреБрдЬрд░рддрд╛ рд╣реИ, рдпрд╣ рд╕рд╛рдмрд┐рдд рдХрд░рддреЗ рд╣реБрдП рдХрд┐ restrict рд╕рд╛рде рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░рдг рдХреЛрдИ рдпреВрдмреА рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ:

  1. copy() рдЗрдирд▓рд╛рдЗрди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдХреБрдЫ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ:
for (int i = 0; i < 3; i++) {
    mat[idxs[i]] = mat[i%2]; mat[i%2] = 7;
}
  1. LLVM рд▓реВрдк рдХреЛ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ:
mat[idxs[0]] = mat[0]; mat[0] = 7; /* from copy(&mat[0%2], &mat[idxs[0]]) */
mat[idxs[1]] = mat[1]; mat[1] = 7; /* from copy(&mat[1%2], &mat[idxs[1]]) */
mat[idxs[2]] = mat[0]; mat[0] = 7; /* from copy(&mat[2%2], &mat[idxs[2]]) */
  1. рдПрд▓рдПрд▓рд╡реАрдПрдо рд╕реЛрдЪрддрд╛ рд╣реИ рдХрд┐ mat[0] mat[idxs[1]] рдпрд╛ mat[1] рд╕рд╛рде рдЙрдкрдирд╛рдо рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдПрд░реНрдЧреЛ рдЗрд╕реЗ mat[0] = 7; рдФрд░ mat[idxs[2]] = mat[0]; рдмреАрдЪ рдмрджрд▓рд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИ рдмрд╛рдж рд╡рд╛рд▓реЗ рдХреЛ mat[idxs[2]] = 7; рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реИрд╢реНрд╡рд┐рдХ рдореВрд▓реНрдп рдХреНрд░рдорд╛рдВрдХрдиред

рд▓реЗрдХрд┐рди mat[0] рд╕рд╛рде рдЙрдкрдирд╛рдо рдХрд░рддрд╛ рд╣реИ mat[idxs[1]] , рдХреНрдпреЛрдВрдХрд┐ idxs[1] == 0 ред рдФрд░ рд╣рдордиреЗ рдпрд╣ рд╡рд╛рджрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рджреВрд╕рд░реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░ рдЬрдм &mat[idxs[1]] рдХреЛ copy , рддреЛ рджреВрд╕рд░рд╛ рддрд░реНрдХ &mat[1] ред рддреЛ LLVM рдХреЛ рдРрд╕рд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд▓рдЧрддрд╛?

рдЦреИрд░, рдЗрд╕реЗ copy рдЗрдирд▓рд╛рдЗрди рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╕реЗ рдХрд░рдирд╛ рд╣реИред рд▓реЛрдб рдФрд░ рд╕реНрдЯреЛрд░ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдкрд░ noalias рдлрд╝рдВрдХреНрд╢рди рд╡рд┐рд╢реЗрд╖рддрд╛ !alias.scope рдФрд░ !noalias рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреА рд╣реИ, рдЬреИрд╕реЗ:

  %8 = load i32, i32* %0, align 4, !tbaa !8, !alias.scope !10, !noalias !13
  store i32 %8, i32* %7, align 4, !tbaa !8, !alias.scope !13, !noalias !10
  store i32 7, i32* %0, align 4, !tbaa !8, !alias.scope !10, !noalias !13

рдЖрдо рддреМрд░ рдкрд░, рдпрджрд┐ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрдИ рдмрд╛рд░ рдЗрдирд▓рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрдкреА рдХреЛ alias.scope рдФрд░ noalias рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЖрдИрдбреА рдорд┐рд▓рддреА рд╣реИ, рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ noalias ( restrict noalias рдЪрд┐рд╣реНрдирд┐рдд рддрд░реНрдХреЛрдВ рдХреА рдЬреЛрдбрд╝реА рдХреЗ рдмреАрдЪ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ 'рдЕрд╕рдорд╛рдирддрд╛' рд╕рдВрдмрдВрдз* рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИред restrict рд╕реА рд╕реНрддрд░ рдкрд░), рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рдорд╛рди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд╣рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓реВрдк рдореЗрдВ рдЗрдирд▓рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рдЗрдирд▓рд╛рдЗрди рдХреЛрдб рдХреЛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рд▓реВрдк рдХреЛ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдФрд░ рдпрд╣ рджреЛрд╣рд░рд╛рд╡ рдЖрдИрдбреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред рдЗрд╕ рдХреА рд╡рдЬрд╣ рд╕реЗ, LLVM рдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд╕реЛрдЪрддрд╛ рд╣реИ рдХрд┐ a 'рд╕реЗ рдХрд┐рд╕реА рдХреЗ рд╕рд╛рде рд░реЛрдВ рд╕рдХрддреЗ рдЙрд░реНрдл b , рд░реЛрдВ рд╣реИ, рдЬреЛ рдЧрд▓рдд рд╣реИ' рдХреНрдпреЛрдВрдХрд┐ a рдкрд╣рд▓реА рдФрд░ рддреАрд╕рд░реА рдХреЙрд▓ рдЙрдкрдирд╛рдо рд╕реЗ рджреВрд╕рд░реА рдХреЙрд▓ рд╕реЗ b (рд╕рднреА &mat[0] рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░рддреЗ рд╣реИрдВ)ред

рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ, рдЬреАрд╕реАрд╕реА рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред (рдХреНрд▓реИрдВрдЧ рдФрд░ рдЬреАрд╕реАрд╕реА -рдУ0 рджреЛрдиреЛрдВ рдЖрдЙрдЯрдкреБрдЯ 7 10 ; рдХреНрд▓реИрдВрдЧ рдПрдЯ -рдУ3 рдЖрдЙрдЯрдкреБрдЯ 7 7 ; рдЬреАрд╕реАрд╕реА рдПрдЯ -рдУ3 рдЖрдЙрдЯрдкреБрдЯ 10 7 ред) рдЙрд╣, рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдХреБрдЫ рдЦрд░рд╛рдм рдХрд░реЗрдВ рдФрд░ рдпреВрдмреА рдХреЛ рдЖрдЦрд┐рд░ рдЬреЛрдбрд╝реЗрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рдХрд┐ рдХреИрд╕реЗ ...

* рдпрд╣ рдЙрд╕рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЪреВрдВрдХрд┐ copy рдХрд┐рд╕реА рднреА рдкреЙрдЗрдВрдЯрд░ рдЕрдВрдХрдЧрдгрд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рджреЛрдиреЛрдВ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЛ рд▓рд┐рдЦрддрд╛ рд╣реИ, рдЕрд╕рдорд╛рдирддрд╛ a != b рдХреЙрд▓ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдФрд░ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдпреВрдмреА рд╣реЛред

рд╕рднреА 33 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВ рдЕрднреА рднреА рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдореБрджреНрджреЗ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдкрд░ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рджрд┐рд▓рдЪрд╕реНрдк рдЯрд┐рдХрдЯ https://github.com/rust-lang/rust/issues/54462 рд╣реИред

@nagisa рдХреЗ рдиреНрдпреВрдирддрдо рдкреНрд░рдЬрдирди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:


рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЕрд╕реБрд░рдХреНрд╖рд┐рдд рдХреЛрдб рдХреЗ рдиреНрдпреВрдирддрдо рдкрд░реАрдХреНрд╖рдг рдХреЗрд╕ (1 рдХреЛрдбрдЬреЗрди рдпреВрдирд┐рдЯ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рди рдХрд░рдирд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ!):

fn linidx(row: usize, col: usize) -> usize {
    row * 1 + col * 3
}

fn swappy() -> [f32; 12] {
    let mut mat = [1.0f32, 5.0, 9.0, 2.0, 6.0, 10.0, 3.0, 7.0, 11.0, 4.0, 8.0, 12.0];

    for i in 0..2 {
        for j in i+1..3 {
            if mat[linidx(j, 3)] > mat[linidx(i, 3)] {
                    for k in 0..4 {
                            let (x, rest) = mat.split_at_mut(linidx(i, k) + 1);
                            let a = x.last_mut().unwrap();
                            let b = rest.get_mut(linidx(j, k) - linidx(i, k) - 1).unwrap();
                            ::std::mem::swap(a, b);
                    }
            }
        }
    }

    mat
}

fn main() {
    let mat = swappy();
    assert_eq!([9.0, 5.0, 1.0, 10.0, 6.0, 2.0, 11.0, 7.0, 3.0, 12.0, 8.0, 4.0], mat);
}

рдореИрдВ рддреНрд░реБрдЯрд┐ рдкреИрджрд╛ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП LLVM рдХреЗ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдкрд╛рд╕ рдХреЛ рджреНрд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ред

рдЗрд╕ рдХрдорд╛рдВрдб рдХреЛ рдЪрд▓рд╛рдиреЗ рд╕реЗ рдХрд╛рд░реНрдп рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рд╣реЛрддрд╛ рд╣реИ ( bug.rs рдХреЛ рдЙрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЗ рдирд╛рдо рд╕реЗ рдмрджрд▓реЗрдВ рдЬрд┐рд╕рдореЗрдВ рдЖрдкрдиреЗ рдкреБрдирд░реБрддреНрдкрд╛рджрди рдХреЛ рд╕рд╣реЗрдЬрд╛ рд╣реИ)ред

rustc -Z no-parallel-llvm -C codegen-units=1 -O -Z mutable-noalias=yes -C llvm-args=-opt-bisect-limit=2260 bug.rs

рдЗрд╕ рдЖрджреЗрд╢ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рджреМрд░рд╛рди рдПрдХ рдЯреВрдЯрд╛ рд╣реБрдЖ рдирд┐рд╖реНрдкрд╛рджрди рдпреЛрдЧреНрдп рдкрд░рд┐рдгрд╛рдо рд╣реЛрддрд╛ рд╣реИ (`assert_eq`` рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИ):

rustc -Z no-parallel-llvm -C codegen-units=1 -O -Z mutable-noalias=yes -C llvm-args=-opt-bisect-limit=2261 bug.rs

рдПрд▓рдПрд▓рд╡реАрдПрдо рджреНрд╡рд┐рднрд╛рдЬрд┐рдд рдЖрдЙрдЯрдкреБрдЯ

рдЗрд╕ рдлрд╝рд╛рдЗрд▓ рдХреЗ рд▓рд┐рдП, рдЕрдиреБрдХреВрд▓рди 2261 Global Value Numbering on function (_ZN3bug6swappy17hdcc51d0e284ea38bE) рдЕрдиреБрд░реВрдк рд╣реИ

рдПрд▓рдПрд▓рд╡реАрдПрдо рд╕рдВрд╢реЛрдзрдиреЛрдВ рдХреЛ рджреНрд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдирд╛ (рдПрд▓рдПрд▓рд╡реАрдПрдорд▓реИрдм рджреНрд╡рд┐рднрд╛рдЬрд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ) рдЗрд╕реЗ r305936-r305938, рд╕рдВрднрд╡рддрдГ r305938 рддрдХ рд╕реАрдорд┐рдд рдХрд░ рджреЗрддрд╛ рд╣реИ:

[BasicAA] рдлрд╝реЙрд▓рдмреИрдХ рдХреЗ рд▓рд┐рдП рдЖрдВрд╢рд┐рдХ рдЙрдкрдирд╛рдо рдХреЗ рдмрдЬрд╛рдп MayAlias тАЛтАЛтАЛтАЛрдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрд╣ рдХрд╛рдлреА рдкреБрд░рд╛рдирд╛ рдмрджрд▓рд╛рд╡ рд╣реИ, рдЬреВрди 2017 рд╕реЗред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдкреНрд░рддрд┐рдмрджреНрдз рд╡рд┐рд╡рд░рдг рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрдЧ рдЙрд╕рд╕реЗ рдкрд╣рд▓реЗ рдореМрдЬреВрдж рдерд╛, рд▓реЗрдХрд┐рди рдмреЗрд╕рд┐рдХрдПрдП рджреНрд╡рд╛рд░рд╛ рдореБрдЦреМрдЯрд╛ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдмрд╛рдж рдореЗрдВ рдЙрдкрдирд╛рдо рдЪрд▓рдиреЗ рд╕реЗ рд░реЛрдХрддрд╛ рд╣реИ, рдЬреЛ рдХрд┐ рдкреНрд░рддрд┐рдмрджреНрдзрддрд╛ рддрдп рдХреА рдЧрдИ рд╣реИред рдорд╛рдорд▓реЗ рдореЗрдВ getelementptr рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рдмреАрдЪ рдПрд▓рд┐рдпрд╛рд╕рд┐рдВрдЧ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬрд╣рд╛рдВ рд╕рдВрдХрд▓рдХ рдЬрд╛рдирддрд╛ рд╣реИ рдХрд┐ рдЙрдирдХреЗ рдкрд╛рд╕ рдПрдХ рд╣реА рдЖрдзрд╛рд░ рдкрддрд╛ рд╣реИ рд▓реЗрдХрд┐рди рдСрдлрд╝рд╕реЗрдЯ рдирд╣реАрдВ рдЬрд╛рдирддрд╛ рд╣реИред

рд╕рдВрдкрд╛рджрд┐рдд 2: рд╕рд╛рде рд╣реА, -enable-scoped-noalias=false рдХреЛ LLVM рд╡рд┐рдХрд▓реНрдк рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд╕ рдХрд░рдирд╛ рдЧрд▓рдд рд╕рдВрдХрд▓рди рдХреЛ рд░реЛрдХрддрд╛ рд╣реИред (рдпрд╣ рдЖрд╢реНрдЪрд░реНрдп рдХреА рдмрд╛рдд рдирд╣реАрдВ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдиреЛрдЖрд▓рд┐рдпрд╛ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдореЗрдВ рдЕрдХреНрд╖рдо рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдпрд╣ рдорджрдж рдХрд░рддрд╛ рд╣реИ ...)

рдкреНрд░реА-рдЬреАрд╡реАрдПрди рдЖрдИрдЖрд░ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рд╕реЗ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣рд╛рдВ рдореВрд▓ рдХрд╛рд░рдг рд▓реВрдк рдЕрдиреЛрд▓рд┐рдВрдЧ рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕ рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдПрд▓рдПрд▓рд╡реАрдПрдо рдПрд▓рд┐рдпрд╛рд╕рд┐рдВрдЧ рдПрдиреЛрдЯреЗрд╢рди рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рдХреА рдореЗрд░реА рд╕рдордЭ рд╕рд╣реА рд╣реИ рдпрд╛ рдирд╣реАрдВред

рдЬреИрд╕реЗ рдХреЛрдб рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ

int *a, *b;
for (int i = 0; i < 4; i++) {
    a[i & 1] = b[i & 1];
}

рдЬрд╣рд╛рдВ a[i & 1] рдФрд░ b[i & 1] рдПрдХ рд╣реА рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рднреАрддрд░ рдЙрдкрдирд╛рдо рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ a рдФрд░ b рдЙрдкрдирд╛рдо рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рдПрд▓рдПрд▓рд╡реАрдПрдо рдЖрдИрдЖрд░ рдореЗрдВ рдпрд╣ рдХреБрдЫ рдРрд╕рд╛ рд╣реЛрдЧрд╛:

define void @test(i32* %addr1, i32* %addr2) {
start:
    br label %body

body:
    %i = phi i32 [ 0, %start ], [ %i2, %body ]
    %j = and i32 %i, 1
    %addr1i = getelementptr inbounds i32, i32* %addr1, i32 %j
    %addr2i = getelementptr inbounds i32, i32* %addr2, i32 %j

    %x = load i32, i32* %addr1i, !alias.scope !2
    store i32 %x, i32* %addr2i, !noalias !2

    %i2 = add i32 %i, 1
    %cmp = icmp slt i32 %i2, 4
    br i1 %cmp, label %body, label %end

end:
    ret void
}

!0 = !{!0}
!1 = !{!1, !0}
!2 = !{!1}

рдпрджрд┐ рд╣рдо рдЗрд╕реЗ -loop-unroll рдорд╛рдзреНрдпрдо рд╕реЗ рдЪрд▓рд╛рддреЗ рд╣реИрдВ рддреЛ рд╣рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИ:

define void @test(i32* %addr1, i32* %addr2) {
start:
  br label %body

body:                                             ; preds = %start
  %x = load i32, i32* %addr1, !alias.scope !0
  store i32 %x, i32* %addr2, !noalias !0
  %addr1i.1 = getelementptr inbounds i32, i32* %addr1, i32 1
  %addr2i.1 = getelementptr inbounds i32, i32* %addr2, i32 1
  %x.1 = load i32, i32* %addr1i.1, !alias.scope !0
  store i32 %x.1, i32* %addr2i.1, !noalias !0
  %x.2 = load i32, i32* %addr1, !alias.scope !0
  store i32 %x.2, i32* %addr2, !noalias !0
  %addr1i.3 = getelementptr inbounds i32, i32* %addr1, i32 1
  %addr2i.3 = getelementptr inbounds i32, i32* %addr2, i32 1
  %x.3 = load i32, i32* %addr1i.3, !alias.scope !0
  store i32 %x.3, i32* %addr2i.3, !noalias !0
  ret void
}

!0 = !{!1}
!1 = distinct !{!1, !2}
!2 = distinct !{!2}

рдиреЛрдЯ рдХрд░реЗрдВ рдХрд┐ рд▓реВрдк рдХреА рд╕рднреА рдЪрд╛рд░ рдкреНрд░рддрд┐рдпрд╛рдВ рд╕рдорд╛рди рдЕрд▓рд┐рдпрд╛рд╕рд┐рдВрдЧ рдбреЛрдореЗрди рдкрд░ рдЕрд▓рд┐рдпрд╛рд╕рд┐рдВрдЧ рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░рддреА рд╣реИрдВред рдПрдХ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдХреЗ рднреАрддрд░ рдиреЛрдЕрд▓рд┐рдпрд╛ рд╣реЛрдиреЗ рдХреЗ рдмрдЬрд╛рдп, рдпрд╣ рдкреВрд░реЗ рдХрд╛рд░реНрдп рдореЗрдВ рдиреЛрдЕрд▓рд┐рдпрд╛ рд╣реИред

рдЕрдВрдд рдореЗрдВ, -scoped-noalias -gvn рд╣рдореЗрдВ рджреЗрддрд╛ рд╣реИ:

define void @test(i32* %addr1, i32* %addr2) {
start:
  %x = load i32, i32* %addr1, !alias.scope !0
  store i32 %x, i32* %addr2, !noalias !0
  %addr1i.1 = getelementptr inbounds i32, i32* %addr1, i32 1
  %addr2i.1 = getelementptr inbounds i32, i32* %addr2, i32 1
  %x.1 = load i32, i32* %addr1i.1, !alias.scope !0
  store i32 %x.1, i32* %addr2i.1, !noalias !0
  store i32 %x, i32* %addr2, !noalias !0
  store i32 %x.1, i32* %addr2i.1, !noalias !0
  ret void
}

!0 = !{!1}
!1 = distinct !{!1, !2}
!2 = distinct !{!2}

рдФрд░ рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдЧрд▓рдд рдкрд░рд┐рдгрд╛рдо рд╣реЛрдВрдЧреЗ рдпрджрд┐ a = b + 1 ред

рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреЗ рд╕рд╛рде рд╕реА рд╕реЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдкреБрди: рдЙрддреНрдкрдиреНрди рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реИ:

#include "stdio.h"

void copy(int * restrict to, int * restrict from) {
    *to = *from;
}

void test(int *a, int *b) {
    for (int i = 0; i < 4; i++) {
        copy(&b[i & 1], &a[i & 1]);
    }
}

int main() {
    int ary[] = {0, 1, 2};
    test(&ary[1], &ary[0]);
    printf("%d %d %d\n", ary[0], ary[1], ary[2]);
    return 1;
}

рдХреНрд▓реИрдВрдЧ 6.0 рдХреЗ рд╕рд╛рде рдпрд╣ 2 2 2 рдХреЛ -O0 рдФрд░ 1 2 2 рдХреЛ -O3 рдкрд░ рдкреНрд░рд┐рдВрдЯ рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдХреЛрдб рд╕реА рдореЗрдВ restrict рд╢рдмреНрджрд╛рд░реНрде рдХреЗ рддрд╣рдд рдХрд╛рдиреВрдиреА рд╣реИ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреЗ рд╕рдЦреНрдд noalias рд╢рдмреНрджрд╛рд░реНрде рдХреЗ рддрд╣рдд рдХрд╛рдиреВрдиреА рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдореИрдВрдиреЗ рдЗрд╕реЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╕реА рдЯреЗрд╕реНрдЯ рдХреЗрд╕ рдореЗрдВ рдШрдЯрд╛ рджрд┐рдпрд╛ (-O3 рдФрд░ -O0 рдкрд░ рд╕рдВрдХрд▓рд┐рдд рдХрд░реЗрдВ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдХреА рддреБрд▓рдирд╛ рдХрд░реЗрдВ):

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>

__attribute__((always_inline))
static inline void copy(int *restrict a, int *restrict b) {
    assert(a != b);
    *b = *a;
    *a = 7;
}

__attribute__((noinline))
void floppy(int mat[static 2], size_t idxs[static 3]) {
    for (int i = 0; i < 3; i++) {
        copy(&mat[i%2], &mat[idxs[i]]);
    }
}

int main() {
    int mat[3] = {10, 20};
    size_t idxs[3] = {1, 0, 1};
    floppy(mat, idxs);
    printf("%d %d\n", mat[0], mat[1]);
}

рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпрджрд┐ рдЖрдк restrict , noalias рдмрд░рд╛рдмрд░ C рдХреЛ рд╣рдЯрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╡реНрдпрд╡рд╣рд╛рд░ рд╕рд╣реА рд╣реИред рдлрд┐рд░ рднреА, assert(a != b) рдЧреБрдЬрд░рддрд╛ рд╣реИ, рдпрд╣ рд╕рд╛рдмрд┐рдд рдХрд░рддреЗ рд╣реБрдП рдХрд┐ restrict рд╕рд╛рде рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдХрд╛рд░рдг рдХреЛрдИ рдпреВрдмреА рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИ:

  1. copy() рдЗрдирд▓рд╛рдЗрди рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдХреБрдЫ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ:
for (int i = 0; i < 3; i++) {
    mat[idxs[i]] = mat[i%2]; mat[i%2] = 7;
}
  1. LLVM рд▓реВрдк рдХреЛ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ:
mat[idxs[0]] = mat[0]; mat[0] = 7; /* from copy(&mat[0%2], &mat[idxs[0]]) */
mat[idxs[1]] = mat[1]; mat[1] = 7; /* from copy(&mat[1%2], &mat[idxs[1]]) */
mat[idxs[2]] = mat[0]; mat[0] = 7; /* from copy(&mat[2%2], &mat[idxs[2]]) */
  1. рдПрд▓рдПрд▓рд╡реАрдПрдо рд╕реЛрдЪрддрд╛ рд╣реИ рдХрд┐ mat[0] mat[idxs[1]] рдпрд╛ mat[1] рд╕рд╛рде рдЙрдкрдирд╛рдо рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдПрд░реНрдЧреЛ рдЗрд╕реЗ mat[0] = 7; рдФрд░ mat[idxs[2]] = mat[0]; рдмреАрдЪ рдмрджрд▓рд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИ рдмрд╛рдж рд╡рд╛рд▓реЗ рдХреЛ mat[idxs[2]] = 7; рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡реИрд╢реНрд╡рд┐рдХ рдореВрд▓реНрдп рдХреНрд░рдорд╛рдВрдХрдиред

рд▓реЗрдХрд┐рди mat[0] рд╕рд╛рде рдЙрдкрдирд╛рдо рдХрд░рддрд╛ рд╣реИ mat[idxs[1]] , рдХреНрдпреЛрдВрдХрд┐ idxs[1] == 0 ред рдФрд░ рд╣рдордиреЗ рдпрд╣ рд╡рд╛рджрд╛ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рджреВрд╕рд░реЗ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рдкрд░ рдЬрдм &mat[idxs[1]] рдХреЛ copy , рддреЛ рджреВрд╕рд░рд╛ рддрд░реНрдХ &mat[1] ред рддреЛ LLVM рдХреЛ рдРрд╕рд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд▓рдЧрддрд╛?

рдЦреИрд░, рдЗрд╕реЗ copy рдЗрдирд▓рд╛рдЗрди рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рд╕реЗ рдХрд░рдирд╛ рд╣реИред рд▓реЛрдб рдФрд░ рд╕реНрдЯреЛрд░ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдкрд░ noalias рдлрд╝рдВрдХреНрд╢рди рд╡рд┐рд╢реЗрд╖рддрд╛ !alias.scope рдФрд░ !noalias рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдореЗрдВ рдмрджрд▓ рдЬрд╛рддреА рд╣реИ, рдЬреИрд╕реЗ:

  %8 = load i32, i32* %0, align 4, !tbaa !8, !alias.scope !10, !noalias !13
  store i32 %8, i32* %7, align 4, !tbaa !8, !alias.scope !13, !noalias !10
  store i32 7, i32* %0, align 4, !tbaa !8, !alias.scope !10, !noalias !13

рдЖрдо рддреМрд░ рдкрд░, рдпрджрд┐ рдХрд┐рд╕реА рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрдИ рдмрд╛рд░ рдЗрдирд▓рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрдкреА рдХреЛ alias.scope рдФрд░ noalias рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЖрдИрдбреА рдорд┐рд▓рддреА рд╣реИ, рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ noalias ( restrict noalias рдЪрд┐рд╣реНрдирд┐рдд рддрд░реНрдХреЛрдВ рдХреА рдЬреЛрдбрд╝реА рдХреЗ рдмреАрдЪ рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ 'рдЕрд╕рдорд╛рдирддрд╛' рд╕рдВрдмрдВрдз* рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИред restrict рд╕реА рд╕реНрддрд░ рдкрд░), рдЬрд┐рд╕рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХреЙрд▓ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рдорд╛рди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред

рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд╣рд▓реЗ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓реВрдк рдореЗрдВ рдЗрдирд▓рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдлрд┐рд░ рдЗрдирд▓рд╛рдЗрди рдХреЛрдб рдХреЛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рд▓реВрдк рдХреЛ рдЕрдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рдФрд░ рдпрд╣ рджреЛрд╣рд░рд╛рд╡ рдЖрдИрдбреА рдирд╣реАрдВ рдмрджрд▓рддрд╛ рд╣реИред рдЗрд╕ рдХреА рд╡рдЬрд╣ рд╕реЗ, LLVM рдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рд╕реЛрдЪрддрд╛ рд╣реИ рдХрд┐ a 'рд╕реЗ рдХрд┐рд╕реА рдХреЗ рд╕рд╛рде рд░реЛрдВ рд╕рдХрддреЗ рдЙрд░реНрдл b , рд░реЛрдВ рд╣реИ, рдЬреЛ рдЧрд▓рдд рд╣реИ' рдХреНрдпреЛрдВрдХрд┐ a рдкрд╣рд▓реА рдФрд░ рддреАрд╕рд░реА рдХреЙрд▓ рдЙрдкрдирд╛рдо рд╕реЗ рджреВрд╕рд░реА рдХреЙрд▓ рд╕реЗ b (рд╕рднреА &mat[0] рдУрд░ рдЗрд╢рд╛рд░рд╛ рдХрд░рддреЗ рд╣реИрдВ)ред

рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ, рдЬреАрд╕реАрд╕реА рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЖрдЙрдЯрдкреБрдЯ рдХреЗ рд╕рд╛рде рдЗрд╕реЗ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред (рдХреНрд▓реИрдВрдЧ рдФрд░ рдЬреАрд╕реАрд╕реА -рдУ0 рджреЛрдиреЛрдВ рдЖрдЙрдЯрдкреБрдЯ 7 10 ; рдХреНрд▓реИрдВрдЧ рдПрдЯ -рдУ3 рдЖрдЙрдЯрдкреБрдЯ 7 7 ; рдЬреАрд╕реАрд╕реА рдПрдЯ -рдУ3 рдЖрдЙрдЯрдкреБрдЯ 10 7 ред) рдЙрд╣, рдореБрдЭреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдХреБрдЫ рдЦрд░рд╛рдм рдХрд░реЗрдВ рдФрд░ рдпреВрдмреА рдХреЛ рдЖрдЦрд┐рд░ рдЬреЛрдбрд╝реЗрдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдпрд╣ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рдХрд┐ рдХреИрд╕реЗ ...

* рдпрд╣ рдЙрд╕рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЪреВрдВрдХрд┐ copy рдХрд┐рд╕реА рднреА рдкреЙрдЗрдВрдЯрд░ рдЕрдВрдХрдЧрдгрд┐рдд рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ рдФрд░ рджреЛрдиреЛрдВ рдкреЙрдЗрдВрдЯрд░реНрд╕ рдХреЛ рд▓рд┐рдЦрддрд╛ рд╣реИ, рдЕрд╕рдорд╛рдирддрд╛ a != b рдХреЙрд▓ рди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдФрд░ рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ рдпреВрдмреА рд╣реЛред

рд╣реЗ, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЙрд╕реА рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП @nikic рдХреЗ рд╕рд╛рде рджреМрдбрд╝ рд▓рдЧрд╛рдИред рдЙрдирдХрд╛ рдЯреЗрд╕реНрдЯ рдХреЗрд╕ рдереЛрдбрд╝рд╛ рдЕрдЪреНрдЫрд╛ рд╣реИ :)

рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╕рдордп рд╣реИ ^^ рд╣рдо рдПрдХ рд╣реА рдирд┐рд╖реНрдХрд░реНрд╖ рдкрд░ рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ рд▓рдЧрднрдЧ рдПрдХ рд╣реА рдХрдо рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдХреЗ рд╕рд╛рде рдкрд╣реБрдВрдЪреЗ :)

рдЗрд╕реЗ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╢рд╛рдпрдж https://github.com/llvm-mirror/llvm/blob/54d4881c352796b18bfe7314662a294754e3a752/lib/Transforms/Utils/InlineFunction.cpp#L801 рдХреА рддрд░реНрдЬ рдкрд░ рдХреБрдЫ рднреА LoopUnrollPass рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдореИрдВрдиреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЗ рд▓рд┐рдП https://bugs.llvm.org/show_bug.cgi?id=39282 рдкрд░ LLVM рдмрдЧ рд░рд┐рдкреЛрд░реНрдЯ рд╕рдмрдорд┐рдЯ рдХреА рд╣реИ

рдФрд░ - рдХреЗрд╡рд▓ рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рддреЗ рд╣реБрдП - рдореИрдВрдиреЗ рдЬреАрд╕реАрд╕реА рдХреЛ рдПрдХ рдмрдЧ рд░рд┐рдкреЛрд░реНрдЯ рдкреНрд░рд╕реНрддреБрдд рдХреА рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдиреЗ рдореЗрд░реЗ рд╕реА рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЗ рдХреЛ рднреА рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рдХрд┐рдпрд╛: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87609

рдЯреНрд░рд╛рдЗрдПрдЬ: рдЕрдЧрд░ рдореИрдВ рдЗрд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрдврд╝ рд░рд╣рд╛ рд╣реВрдВ, рддреЛ рдПрд▓рдПрд▓рд╡реАрдПрдо рдлрд┐рдХреНрд╕ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (https://reviews.llvm.org/D9375)ред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрд▓рдПрд▓рд╡реАрдПрдо рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд┐рд▓рдп рдХреЗ рд▓рд┐рдП рдЗрд╕рдХрд╛ рдХреНрдпрд╛ рдЕрд░реНрде рд╣реИ, рдпрд╛ рдЬрдм рдРрд╕рд╛ рд╣реБрдЖ; рдПрд▓рдПрд▓рд╡реАрдПрдо рдХреА рд╕рдВрд╢реЛрдзрди рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░ рдХрд┐рд╕реА рдХреЛ рдпрд╣ рдЬрд╛рдВрдЪрдирд╛ рдЪрд╛рд╣рд┐рдП рдХрд┐ рдХреНрдпрд╛ рд╕рдорд╕реНрдпрд╛ рдЕрднреА рдареАрдХ рд╣реЛ рдЧрдИ рд╣реИ (рдФрд░ рдХрд┐рди рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП)ред

рдЗрд╕реЗ рдорд░реНрдЬ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╕рдореАрдХреНрд╖рд╛ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдереЛрдбрд╝реА рдЕрдЬреАрдм рдереА рдФрд░ рдЬрд┐рд╕ рд╡реНрдпрдХреНрддрд┐ рдиреЗ рдЗрд╕реЗ рдареАрдХ рдХрд┐рдпрд╛ рд╡рд╣ рдЕрдм рдкреИрдЪ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

"рдкреВрд░реНрдг рдкреНрд░рддрд┐рдмрдВрдз" рдкреИрдЪ рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрд╣ рд╢рд╛рдпрдж рдореВрд▓реНрдпрд╡рд╛рди рд╣реЛрдЧрд╛ рдпрджрд┐ рдХрд┐рд╕реА рдиреЗ llvm рдХреЗ рд╢реАрд░реНрд╖ рдкрд░ рд░рд╕реНрдЯ рдореЗрдВ noalias рдХреЛ рдлрд┐рд░ рд╕реЗ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд┐рдпрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдкреИрдЪ рд╕реЗрдЯ рд▓рд╛рдЧреВ рд╣реИред

рдореИрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкреНрд░рдпрд╛рд╕ рдХрд░рдиреЗ рдХреЛ рддреИрдпрд╛рд░ рд╣реВрдВред
рдореЗрд░реЗ рдкрд╛рд╕ рдордзреНрдпрдо рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рд╕рд░реНрд╡рд░ (48 HT рдХреЛрд░, 128G RAM) рддрдХ рдкрд╣реБрдВрдЪ рд╣реИ рдФрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореИрдВ рдкреИрдЪ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдмрдВрдзрди рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред
рдПрдХ рдмрд╛рд░ рдЬрдм рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдЯреВрд▓рдЪреЗрди рд╣реЛ, рддреЛ рдЖрдк рдХрд┐рд╕ рдХреНрд░реЗрдЯ рдХреЛ рдЖрдЬрд╝рдорд╛рдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрдВрдЧреЗ?

рдореИрдВрдиреЗ llvm рдХреЗ рдЕрдкрд╕реНрдЯреНрд░реАрдо рдорд╛рд╕реНрдЯрд░ рдкрд░ рд╕рднреА рд░рд╕реНрдЯ-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрдорд┐рдЯреНрд╕ рдХреЛ рдорд░реНрдЬ рдХрд░рдирд╛ рд╕рдорд╛рдкреНрдд рдХрд░ рджрд┐рдпрд╛ рдФрд░ рдлрд┐рд░ рдкреИрдЪ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ред
рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдореА рд╢рд╛рдЦрд╛ рд╣реИ: https://github.com/PaulGrandperrin/llvm-project/tree/llvm-master-with-rustlang-patches-and-D69542
рдЕрдм рдореИрдВ рдЯреВрд▓рдЪреЗрди рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдБрдЧрд╛ рдФрд░ рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛рдКрдБрдЧрд╛

рдкрд╣рд▓реЗ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдк рд╡рд╛рдкрд╕ рд▓реМрдЯрддреЗ рд╣реИрдВ: https://github.com/rust-lang/rust/pull/54639 рддрд╛рдХрд┐ рдЬрдВрдЧ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдиреЛрд▓рд┐рдпрд╛рд╕ рдЙрддреНрд╕рд░реНрдЬрд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реИред

рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рд╡рд╛рд▓реА рдкрд╣рд▓реА рдЕрдЪреНрдЫреА рдЪреАрдЬрд╝ рдХреБрдЫ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

pub fn adds(a: &mut i32, b: &mut i32) {
    *a += *b;
    *a += *b;
}

рдФрд░ рдкреБрд╖реНрдЯрд┐ рдХрд░реЗрдВ рдХрд┐ рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕рдВрдХрд▓рд┐рдд рдХрд░рддрд╛ рд╣реИ:

example::adds:
        mov     eax, dword ptr [rsi]
        add     eax, eax
        add     dword ptr [rdi], eax
        ret

рдФрд░ рдирд╣реАрдВ

example::adds:
        mov     eax, dword ptr [rdi]
        add     eax, dword ptr [rsi]
        mov     dword ptr [rdi], eax
        add     eax, dword ptr [rsi]
        mov     dword ptr [rdi], eax
        ret

рдЗрд╕рдХреЗ рдмрд╛рдж, рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░реЗрдВ рдХрд┐ https://github.com/rust-lang/rust/issues/54462#issue -362850708 рдХрд╛ рдХреЛрдб рдЕрдм рдЧрд▓рдд рдирд╣реАрдВ рд╣реИред

@jrmuizel рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ # 54639 рдХрд░рддрд╛ @nagisa рд╢рд╛рдорд┐рд▓ рдХреА рдиреНрдпреВрдирддрдо рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдкреНрд░рд╕реНрддреБрдд рдПрдХ рдирдпрд╛ рд╕рдВрдХрд▓рдХ рдкрд░реАрдХреНрд╖рдг рдХреЗ рд░реВрдк рдореЗрдВ # 54,462 рдХреЗ рд▓рд┐рдПред рд╢рд╛рдпрдж рдПрдХ рдкреВрд░реНрдг рд╡рд╛рдкрд╕реА рдХреНрд░рдо рдореЗрдВ рдирд╣реАрдВ рд╣реИ?

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЗрд╕реЗ рд╢рд╛рдорд┐рд▓ рдХрд░рдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ рдпрд╛ рдирд╣реАрдВ рдХреНрдпреЛрдВрдХрд┐ AFAIK рдпрд╣ рдХреЗрд╡рд▓ рдХреБрдЫ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдзреНрд╡рдЬ рдХреЛ рдмрджрд▓рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ (рдЬрд┐рд╕реЗ -Zmutable-noalias=yes рдУрд╡рд░рд░рд╛рдЗрдб рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ) рдФрд░ рдореИрдВ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдкрд░реАрдХреНрд╖рдг рдлрд╝рд╛рдЗрд▓ рдХреЛ рд╕рдВрдХрд▓рд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред

рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдореИрдВ рдЕрднреА рднреА рдПрд▓рдПрд▓рд╡реАрдПрдо рдмрдирд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдЕрднреА рддрдХ рдореБрдЭреЗ рдЬрдВрдЧ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдкреИрдЪ рдХреЗ рд╕рд╛рде рдпрд╛ рдЙрд╕рдХреЗ рдмрд┐рдирд╛ рдПрдХ рд╕рдВрдХрд▓рди рддреНрд░реБрдЯрд┐ рдорд┐рд▓рддреА рд╣реИ (рдпрд╛рдиреА: рдмрд╕ рдЕрдкрд╕реНрдЯреНрд░реАрдо рдХрд╛ рдПрд▓рдПрд▓рд╡реАрдПрдо рдорд╛рд╕реНрдЯрд░ + рдкреИрдЪ рднреА рд╡рд┐рдлрд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ):

In file included from /usr/include/c++/8/cmath:45,
                 from /opt/rust/src/llvm-project/llvm/include/llvm-c/DataTypes.h:28,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/Support/DataTypes.h:16,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/ADT/Hashing.h:47,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/ADT/ArrayRef.h:12,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/Transforms/Utils/NoAliasUtils.h:16,
                 from /opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:13:
/opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp: In function тАШvoid llvm::cloneNoAliasScopes(llvm::ArrayRef<llvm::MetadataAsValue*>, llvm::DenseMap<llvm::MDN
ode*, llvm::MDNode*>&, llvm::DenseMap<llvm::MetadataAsValue*, llvm::MetadataAsValue*>&, llvm::StringRef, llvm::LLVMContext&)тАЩ:
/opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:174:30: error: no matching function for call to тАШllvm::AliasScopeNode::AliasScopeNode(double)тАЩ
         llvm::AliasScopeNode SNAN(MD);
                              ^~~~
In file included from /opt/rust/src/llvm-project/llvm/include/llvm/IR/TrackingMDRef.h:16,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/IR/DebugLoc.h:17,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/IR/Instruction.h:21,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/IR/BasicBlock.h:22,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/IR/Instructions.h:27,
                 from /opt/rust/src/llvm-project/llvm/include/llvm/Transforms/Utils/NoAliasUtils.h:22,
                 from /opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:13:
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1446:12: note: candidate: тАШllvm::AliasScopeNode::AliasScopeNode(const llvm::MDNode*)тАЩ
   explicit AliasScopeNode(const MDNode *N) : Node(N) {}
            ^~~~~~~~~~~~~~
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1446:12: note:   no known conversion for argument 1 from тАШdoubleтАЩ to тАШconst llvm::MDNode*тАЩ
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1445:3: note: candidate: тАШconstexpr llvm::AliasScopeNode::AliasScopeNode()тАЩ
   AliasScopeNode() = default;
   ^~~~~~~~~~~~~~
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1445:3: note:   candidate expects 0 arguments, 1 provided
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1441:7: note: candidate: тАШconstexpr llvm::AliasScopeNode::AliasScopeNode(const llvm::AliasScopeNode&)тАЩ
 class AliasScopeNode {
       ^~~~~~~~~~~~~~
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1441:7: note:   no known conversion for argument 1 from тАШdoubleтАЩ to тАШconst llvm::AliasScopeNode&тАЩ
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1441:7: note: candidate: тАШconstexpr llvm::AliasScopeNode::AliasScopeNode(llvm::AliasScopeNode&&)тАЩ
/opt/rust/src/llvm-project/llvm/include/llvm/IR/Metadata.h:1441:7: note:   no known conversion for argument 1 from тАШdoubleтАЩ to тАШllvm::AliasScopeNode&&тАЩ
/opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:177:31: error: request for member тАШgetNameтАЩ in тАШ__builtin_nans(((const char*)""))тАЩ, which is of non-class ty
pe тАШdoubleтАЩ
         auto ScopeName = SNAN.getName();
                               ^~~~~~~
/opt/rust/src/llvm-project/llvm/lib/Transforms/Utils/NoAliasUtils.cpp:187:39: error: request for member тАШgetDomainтАЩ in тАШ__builtin_nans(((const char*)""))тАЩ, which is of non-class
type тАШdoubleтАЩ
             const_cast<MDNode *>(SNAN.getDomain()), Name);
                                       ^~~~~~~~~
[ 75%] Building CXX object lib/Target/Hexagon/CMakeFiles/LLVMHexagonCodeGen.dir/RDFCopy.cpp.o
make[2]: *** [lib/Transforms/Utils/CMakeFiles/LLVMTransformUtils.dir/build.make:635: lib/Transforms/Utils/CMakeFiles/LLVMTransformUtils.dir/NoAliasUtils.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....

рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдПрд▓рдПрд▓рд╡реАрдПрдо рдорд╛рд╕реНрдЯрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреИрдЪ рдХреЗ рд╕рд╛рде рд╕рд┐рдВрдХ рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛ рдЧрдпрд╛ рд╣реЛ (рдЬреЛ рдпрд╣ рджреЗрдЦрддреЗ рд╣реБрдП рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдХрд┐ рдкреИрдЪ рдХрд┐рддрдирд╛ рдмрдбрд╝рд╛ рд╣реИ рдФрд░ рдПрд▓рдПрд▓рд╡реАрдПрдо рдорд╛рд╕реНрдЯрд░ рдХрд┐рддрдиреА рддреЗрдЬреА рд╕реЗ рдЖрдЧреЗ рдмрдврд╝ рд░рд╣рд╛ рд╣реИ) рдФрд░ рдЖрдкрдХреЛ рдПрд▓рдПрд▓рд╡реАрдПрдо рдорд╛рд╕реНрдЯрд░ рдХреЗ рдкреБрд░рд╛рдиреЗ рд╕рдВрд╢реЛрдзрди рдХреЗ рдЦрд┐рд▓рд╛рдл рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ? рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдкреИрдЪ рд▓реЗрдЦрдХ рдХреЛ рдкрд┐рдВрдЧ рдХрд░рдирд╛ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рд╛рд░реНрдердХ рд╣реЛрдЧрд╛ред

рдкреИрдЪ рдХреЗ рд╕рд╛рде рдмрдирдиреЗ рд╡рд╛рд▓реЗ рдкреБрд░рд╛рдиреЗ рд╕рдВрд╢реЛрдзрди рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ, рдареАрдХ рдпрд╣реА рдореИрдВ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ :-)

рдореБрдЭреЗ рдЕрдм рдпрдХреАрди рд╣реИ рдХрд┐ рд╕рдорд╕реНрдпрд╛ llvm/рдорд╛рд╕реНрдЯрд░ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рд╣реИ рдмрд▓реНрдХрд┐ рдкреИрдЪ рд╕реЗ рд╣реИред
llvm/master рдХреА рд╕рдмрд╕реЗ рдкреБрд░рд╛рдиреА рдХрдорд┐рдЯрдореЗрдВрдЯ рдЬреЛ рдЕрднреА рднреА рдкреИрдЪ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрдд рд╣реИ, рд╡рд╣ рд╣реИ https://github.com/llvm/llvm-project/commit/5b99c189b3bfc0faa157f7ca39652c0bb8c315a7 рд▓реЗрдХрд┐рди рдЗрд╕рд╕реЗ рднреА рдкрд╣рд▓реЗ рдкреИрдЪ рдХрдВрдкрд╛рдЗрд▓ рдХрд░рдиреЗ рдореЗрдВ рд╡рд┐рдлрд▓ рд░рд╣рддрд╛ рд╣реИред
рдореИрдВ рдЕрдм рд╕реА ++ рдХреЛ рд╕рдордЭрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдердХрд╛ рд╣реБрдЖ рдФрд░ рдЖрд▓рд╕реА рд╣реВрдВ, рдореИрдВ рдХрд▓ рдлрд┐рд░ рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред
рдЗрд╕ рдмреАрдЪ, рдХреНрдпрд╛ рдХреЛрдИ рдорджрдж рдорд╛рдВрдЧрдиреЗ рдХреЗ рд▓рд┐рдП рдкреИрдЪ рдХреЗ рд▓реЗрдЦрдХ рд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд░ рд╕рдХрддрд╛ рд╣реИ?

рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдЖрдк rustllvm рдХреЛ рдкреИрдЪ рдХрд┐рдП рдмрд┐рдирд╛ рд░рд╕реНрдЯ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рдж) рдХреЗ рд╕рд╛рде рдорд╛рд╕реНрдЯрд░ рдПрд▓рдПрд▓рд╡реАрдПрдо рдХрд╛ рдЖрд╕рд╛рдиреА рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░

@ mati865 рдореИрдВрдиреЗ рдкрд╣рд▓реЗ рдЬрдВрдЧ рдХреЗ llvm-9 рдХрд╛рдВрдЯреЗ рдкрд░ рдкреИрдЪ рд▓рдЧрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА, рд▓реЗрдХрд┐рди рдпрд╣ рдмрд╣реБрдд рдорд╛рдореВрд▓реА рднреА рдирд╣реАрдВ рдерд╛ ...

рдкреИрдЪ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ llvm/ llvm-project@82d3ba87d06f9e2abc6e27d8799587d433c56630 рдХреЗ рд╢реАрд░реНрд╖ рдкрд░

@jrmuizel рдзрдиреНрдпрд╡рд╛рдж рдореИрдВ рдХреЛрд╢рд┐рд╢ рдХрд░реВрдБрдЧрд╛!
рдЗрд╕ рдмреАрдЪ, рдореИрдВ llvm рдорд╛рд╕реНрдЯрд░ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрдорд╛рдг рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП rustllvm рдХреЛ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реВрдВред

рдкрд┐рдВрдЧ @PaulGrandperrin , рдХреЛрдИ рдЕрдкрдбреЗрдЯ?

https://reviews.llvm.org/D68484

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЕрдиреБрдорд╛рдирд┐рдд рд╕рдордпрд░реЗрдЦрд╛ рдХреНрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдЖрдХрд╛рд░ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдЗрд╕ рдкреИрдЪ рдХреЗ рдХрднреА рднреА рд╡рд┐рд▓рдп рд╣реЛрдиреЗ рдХреА рдХреБрд▓ рд╕рдВрднрд╛рд╡рдирд╛ рдХреНрдпрд╛ рд╣реИ?

@MSxDOS рдЖрдк

рдпрд╣рд╛рдБ рдирд╡реАрдирддрдо рд╕реНрдерд┐рддрд┐ рд╣реИ рдЬреЛ рдореИрдВрдиреЗ рджреЗрдЦреА рд╣реИ: https://reviews.llvm.org/D69542#1836439

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдмрд┐рдВрджреБ рдкрд░ рдпрд╣ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдирд╣реАрдВ рд░рд╣реЗрдЧрд╛ рдпрджрд┐ https://github.com/bytecodealliance/cranelift~~ https://github.com/bjorn3/rustc_codegen_cranelift рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ?

@leeoniya , рдСрдкреНрдЯ рдмрд┐рд▓реНрдб рдХреЗ рд▓рд┐рдП рдХреНрд░реЗрдирд▓рд┐рдлреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдХреЛрдИ рдЕрд▓реНрдкрдХрд╛рд▓рд┐рдХ рдпреЛрдЬрдирд╛ рдирд╣реАрдВ рд╣реИред рдХреНрд░реЗрдирд▓рд┐рдлреНрдЯ рдореЗрдВ рдЕрдиреБрдХреВрд▓рди рдХрд╛рд░реНрдп рдХрд╛ рдПрдХ рдЧреБрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ рдЬреЛ рдЗрд╕реЗ рд╕рдВрднрд╡ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ред

рдореБрдЭреЗ рдпрд╣ рдЬрд╛рдирдХрд░ рдЖрд╢реНрдЪрд░реНрдп рд╣реБрдЖ рдХрд┐ рдЗрд╕ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдмрд┐рдирд╛ рдЕрд▓рд┐рдпрд╛рд╕рд┐рдВрдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдпрд╣ рдорд╛рдирдиреЗ рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рд╕рдВрдХрд▓рдХ рдХрд┐рддрдирд╛ рд░реВрдврд╝рд┐рд╡рд╛рджреА рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

fn baz(s: &mut S) {
    if s.y < 10 {
        s.x = foo();
    }

    if s.y < 5 {
        s.x = foo();
    }
}

рдЪреВрдВрдХрд┐ рдпрд╣ &mut рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрд░рдЪрдирд╛ рд╕рджрд╕реНрдпреЛрдВ рддрдХ рдкрд╣реБрдВрдЪрддрд╛ рд╣реИ, рдпрд╣ рдорд╛рдирддрд╛ рд╣реИ рдХрд┐ s.x рдФрд░ s.y рдЙрдкрдирд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП s.y рд▓рд┐рдП рдПрдХ рдХреЗ рдмрдЬрд╛рдп рджреЛ рдореЗрдореЛрд░реА рдПрдХреНрд╕реЗрд╕ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рджреБрд░реНрднрд╛рдЧреНрдпрдкреВрд░реНрдг рд╣реИ, рдЬрдм рдЖрдк рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╕рджрд╕реНрдп рдХрд┐рддрдиреА рдмрд╛рд░ рдкрдврд╝рддрд╛/рд▓рд┐рдЦрддрд╛ рд╣реИ &mut рдорд╛рдзреНрдпрдо рд╕реЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрдХреНрд░рдо рдореЗрдВ рдЗрдВрдЯрд░рд▓реАрд╡ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдХреБрдЫ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдРрд╕реЗ рд╕рднреА рдкрдврд╝рдиреЗ/рд▓рд┐рдЦрдиреЗ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЖрд╢реНрдЪрд░реНрдп рдХреА рдмрд╛рдд рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдЧрд░ рдРрд╕рд╛ рд╣реЛрддрд╛ рд╣реИ рддреЛ рд╢рд╛рдпрдж рдпрд╣ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рд░ рджреЗрдЧрд╛ред рдлрд┐рд░ рднреА, -Z mutable-noalias рдЙрдкрдпреЛрдЧ рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдбрдмрд▓ рдореЗрдореЛрд░реА рдПрдХреНрд╕реЗрд╕ рдХреЛ рдареАрдХ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдХрд╛ рднрдВрдбрд╛рдлреЛрдбрд╝ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

@PaulGrandperrin рдЗрд╕ рдкреИрдЪ рдЕрдк рдХрд╛ рдПрдХ рдирдпрд╛ рд╕рдВрд╕реНрдХрд░рдг https://reviews.llvm.org/D69542 llvm@9fb46a452d4e5666828c95610ceac8dcd9e4ce16 рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реИ

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

dwrensha picture dwrensha  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

overvenus picture overvenus  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

cuviper picture cuviper  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

eddyb picture eddyb  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dnsl48 picture dnsl48  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ