Skip to content

unlikely intrinsic does not work #88767

Closed
@stepancheg

Description

@stepancheg

Code:

#![feature(core_intrinsics)]

use std::intrinsics::unlikely;

extern "C" {
    fn aaa() -> u32;
    fn bbb() -> u32;
}

pub unsafe fn foo(a: bool) -> u32 {
    if unlikely(a) { aaa() } else { bbb() }
}

Compiler explorer

rustc 1.57.0-nightly (fdf6505 2021-09-07)

Generates assembly:

example::foo:
        test    edi, edi
        je      .LBB0_1
        jmp     qword ptr [rip + aaa@GOTPCREL]
.LBB0_1:
        jmp     qword ptr [rip + bbb@GOTPCREL]

If unlikely worked, call to aaa would be after jump (it works if aaa is marked #[cold] for example).

Unlikely is present in Rust MIR:

fn foo(_1: bool) -> u32 {
    debug a => _1;                       // in scope 0 at /app/example.rs:10:19: 10:20
    let mut _0: u32;                     // return place in scope 0 at /app/example.rs:10:31: 10:34
    let mut _2: bool;                    // in scope 0 at /app/example.rs:11:8: 11:19
    let mut _3: bool;                    // in scope 0 at /app/example.rs:11:17: 11:18

    bb0: {
        _3 = _1;                         // scope 0 at /app/example.rs:11:17: 11:18
        _2 = unlikely(move _3) -> bb1;   // scope 0 at /app/example.rs:11:8: 11:19
                                         // mir::Constant
                                         // + span: /app/example.rs:11:8: 11:16
                                         // + literal: Const { ty: extern "rust-intrinsic" fn(bool) -> bool {std::intrinsics::unlikely}, val: Value(Scalar(<ZST>)) }
    }

    bb1: {
        switchInt(move _2) -> [false: bb3, otherwise: bb2]; // scope 0 at /app/example.rs:11:8: 11:19
    }

    bb2: {
        _0 = aaa() -> bb4;               // scope 0 at /app/example.rs:11:22: 11:27
                                         // mir::Constant
                                         // + span: /app/example.rs:11:22: 11:25
                                         // + literal: Const { ty: unsafe extern "C" fn() -> u32 {aaa}, val: Value(Scalar(<ZST>)) }
    }

    bb3: {
        _0 = bbb() -> bb4;               // scope 0 at /app/example.rs:11:37: 11:42
                                         // mir::Constant
                                         // + span: /app/example.rs:11:37: 11:40
                                         // + literal: Const { ty: unsafe extern "C" fn() -> u32 {bbb}, val: Value(Scalar(<ZST>)) }
    }

    bb4: {
        return;                          // scope 0 at /app/example.rs:12:2: 12:2
    }
}

but it is lost in LLVM IR:

define i32 @_ZN7example3foo17hdda9a45d5ad75400E(i1 zeroext %a) unnamed_addr #0 !dbg !6 {
start:
  br i1 %a, label %bb2, label %bb3, !dbg !10

bb3:                                              ; preds = %start
  %0 = tail call i32 @bbb(), !dbg !11
  br label %bb4, !dbg !11

bb2:                                              ; preds = %start
  %1 = tail call i32 @aaa(), !dbg !12
  br label %bb4, !dbg !12

bb4:                                              ; preds = %bb3, %bb2
  %.0 = phi i32 [ %1, %bb2 ], [ %0, %bb3 ], !dbg !13
  ret i32 %.0, !dbg !14
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.I-slowIssue: Problems and improvements with respect to performance of generated code.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions