-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of #122320 - erikdesjardins:vtable, r=nikic
Use ptradd for vtable indexing Extension of #121665. After this, the only remaining usages of GEP are [this](https://github.com/rust-lang/rust/blob/cd81f5b27ee00b49d413db50b5e6af871cebcf23/compiler/rustc_codegen_llvm/src/intrinsic.rs#L909-L920) kinda janky Emscription EH code, which I'll change in a future PR, and array indexing / pointer offsets, where there isn't yet a canonical `ptradd` form. (Out of curiosity I tried converting the latter to `ptradd(ptr, mul(size, index))`, but that causes codegen regressions right now.) r? `@nikic`
- Loading branch information
Showing
4 changed files
with
104 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
//! This file tests that we correctly generate GEP instructions for vtable upcasting. | ||
//@ compile-flags: -C no-prepopulate-passes -Copt-level=0 | ||
|
||
#![crate_type = "lib"] | ||
#![feature(trait_upcasting)] | ||
|
||
pub trait Base { | ||
fn base(&self); | ||
} | ||
|
||
pub trait A : Base { | ||
fn a(&self); | ||
} | ||
|
||
pub trait B : Base { | ||
fn b(&self); | ||
} | ||
|
||
pub trait Diamond : A + B { | ||
fn diamond(&self); | ||
} | ||
|
||
// CHECK-LABEL: upcast_a_to_base | ||
#[no_mangle] | ||
pub fn upcast_a_to_base(x: &dyn A) -> &dyn Base { | ||
// Requires no adjustment, since its vtable is extended from `Base`. | ||
|
||
// CHECK: start: | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: ret | ||
x as &dyn Base | ||
} | ||
|
||
// CHECK-LABEL: upcast_b_to_base | ||
#[no_mangle] | ||
pub fn upcast_b_to_base(x: &dyn B) -> &dyn Base { | ||
// Requires no adjustment, since its vtable is extended from `Base`. | ||
|
||
// CHECK: start: | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: ret | ||
x as &dyn Base | ||
} | ||
|
||
// CHECK-LABEL: upcast_diamond_to_a | ||
#[no_mangle] | ||
pub fn upcast_diamond_to_a(x: &dyn Diamond) -> &dyn A { | ||
// Requires no adjustment, since its vtable is extended from `A` (as the first supertrait). | ||
|
||
// CHECK: start: | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: ret | ||
x as &dyn A | ||
} | ||
|
||
// CHECK-LABEL: upcast_diamond_to_b | ||
// CHECK-SAME: (ptr align {{[0-9]+}} [[DATA_PTR:%.+]], ptr align {{[0-9]+}} [[VTABLE_PTR:%.+]]) | ||
#[no_mangle] | ||
pub fn upcast_diamond_to_b(x: &dyn Diamond) -> &dyn B { | ||
// Requires adjustment, since it's a non-first supertrait. | ||
|
||
// CHECK: start: | ||
// CHECK-NEXT: [[UPCAST_SLOT_PTR:%.+]] = getelementptr inbounds i8, ptr [[VTABLE_PTR]] | ||
// CHECK-NEXT: [[UPCAST_VTABLE_PTR:%.+]] = load ptr, ptr [[UPCAST_SLOT_PTR]] | ||
// CHECK-NEXT: [[FAT_PTR_1:%.+]] = insertvalue { ptr, ptr } poison, ptr [[DATA_PTR]], 0 | ||
// CHECK-NEXT: [[FAT_PTR_2:%.+]] = insertvalue { ptr, ptr } [[FAT_PTR_1]], ptr [[UPCAST_VTABLE_PTR]], 1 | ||
// CHECK-NEXT: ret { ptr, ptr } [[FAT_PTR_2]] | ||
x as &dyn B | ||
} | ||
|
||
// CHECK-LABEL: upcast_diamond_to_b | ||
#[no_mangle] | ||
pub fn upcast_diamond_to_base(x: &dyn Diamond) -> &dyn Base { | ||
// Requires no adjustment, since `Base` is the first supertrait of `A`, | ||
// which is the first supertrait of `Diamond`. | ||
|
||
// CHECK: start: | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: insertvalue | ||
// CHECK-NEXT: ret | ||
x as &dyn Base | ||
} |