diff options
Diffstat (limited to 'tests/codegen')
| -rw-r--r-- | tests/codegen/asm-maybe-uninit.rs | 27 | ||||
| -rw-r--r-- | tests/codegen/box-uninit-bytes.rs (renamed from tests/codegen/box-maybe-uninit.rs) | 14 | ||||
| -rw-r--r-- | tests/codegen/cold-call-declare-and-call.rs | 13 | ||||
| -rw-r--r-- | tests/codegen/debuginfo-inline-callsite-location.rs | 28 | ||||
| -rw-r--r-- | tests/codegen/issues/issue-115385-llvm-jump-threading.rs | 46 | ||||
| -rw-r--r-- | tests/codegen/lib-optimizations/iter-sum.rs | 15 | ||||
| -rw-r--r-- | tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs | 4 | ||||
| -rw-r--r-- | tests/codegen/mem-replace-simple-type.rs | 21 | ||||
| -rw-r--r-- | tests/codegen/move-before-nocapture-ref-arg.rs | 22 | ||||
| -rw-r--r-- | tests/codegen/repr/transparent.rs | 1 | ||||
| -rw-r--r-- | tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs | 43 | ||||
| -rw-r--r-- | tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs | 12 | ||||
| -rw-r--r-- | tests/codegen/slice-as_chunks.rs | 6 | ||||
| -rw-r--r-- | tests/codegen/slice-iter-nonnull.rs | 6 | ||||
| -rw-r--r-- | tests/codegen/sroa-fragment-debuginfo.rs | 46 | ||||
| -rw-r--r-- | tests/codegen/swap-small-types.rs | 33 | ||||
| -rw-r--r-- | tests/codegen/tuple-layout-opt.rs | 1 |
17 files changed, 305 insertions, 33 deletions
diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm-maybe-uninit.rs new file mode 100644 index 00000000000..d7e4a948954 --- /dev/null +++ b/tests/codegen/asm-maybe-uninit.rs @@ -0,0 +1,27 @@ +// compile-flags: -O +// only-x86_64 + +#![crate_type = "rlib"] +#![allow(asm_sub_register)] + +use std::mem::MaybeUninit; +use std::arch::asm; + +// CHECK-LABEL: @int +#[no_mangle] +pub unsafe fn int(x: MaybeUninit<i32>) -> MaybeUninit<i32> { + let y: MaybeUninit<i32>; + asm!("/*{}{}*/", in(reg) x, out(reg) y); + y +} + +// CHECK-LABEL: @inout +#[no_mangle] +pub unsafe fn inout(mut x: i32) -> MaybeUninit<u32> { + let mut y: MaybeUninit<u32>; + asm!("/*{}*/", inout(reg) x => y); + asm!("/*{}*/", inout(reg) y => x); + asm!("/*{}*/", inlateout(reg) x => y); + asm!("/*{}*/", inlateout(reg) y => x); + y +} diff --git a/tests/codegen/box-maybe-uninit.rs b/tests/codegen/box-uninit-bytes.rs index 282af99b067..732da0a1794 100644 --- a/tests/codegen/box-maybe-uninit.rs +++ b/tests/codegen/box-uninit-bytes.rs @@ -25,6 +25,20 @@ pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> { Box::new(MaybeUninit::uninit()) } +#[repr(align(1024))] +pub struct LotsaPadding(usize); + +// Boxing a value with padding should not copy junk from the stack +#[no_mangle] +pub fn box_lotsa_padding() -> Box<LotsaPadding> { + // CHECK-LABEL: @box_lotsa_padding + // CHECK-NOT: alloca + // CHECK-NOT: getelementptr + // CHECK-NOT: memcpy + // CHECK-NOT: memset + Box::new(LotsaPadding(42)) +} + // Hide the `allocalign` attribute in the declaration of __rust_alloc // from the CHECK-NOT above, and also verify the attributes got set reasonably. // CHECK: declare {{(dso_local )?}}noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]] diff --git a/tests/codegen/cold-call-declare-and-call.rs b/tests/codegen/cold-call-declare-and-call.rs index 71d49478bfc..572dc407f51 100644 --- a/tests/codegen/cold-call-declare-and-call.rs +++ b/tests/codegen/cold-call-declare-and-call.rs @@ -1,12 +1,21 @@ +// revisions: NORMAL WINDOWS // compile-flags: -C no-prepopulate-passes +//[NORMAL] ignore-windows +//[WINDOWS] only-windows +//[WINDOWS] only-x86_64 #![crate_type = "lib"] #![feature(rust_cold_cc)] // wasm marks the definition as `dso_local`, so allow that as optional. -// CHECK: define{{( dso_local)?}} coldcc void @this_should_never_happen(i16 -// CHECK: call coldcc void @this_should_never_happen(i16 +// NORMAL: define{{( dso_local)?}} preserve_mostcc void @this_should_never_happen(i16 +// NORMAL: call preserve_mostcc void @this_should_never_happen(i16 + +// See the comment in `Target::adjust_abi` for why this differs + +// WINDOWS: define void @this_should_never_happen(i16 +// WINDOWS: call void @this_should_never_happen(i16 #[no_mangle] pub extern "rust-cold" fn this_should_never_happen(x: u16) {} diff --git a/tests/codegen/debuginfo-inline-callsite-location.rs b/tests/codegen/debuginfo-inline-callsite-location.rs new file mode 100644 index 00000000000..b1475ee7931 --- /dev/null +++ b/tests/codegen/debuginfo-inline-callsite-location.rs @@ -0,0 +1,28 @@ +// compile-flags: -g -O + +// Check that each inline call site for the same function uses the same "sub-program" so that LLVM +// can correctly merge the debug info if it merges the inlined code (e.g., for merging of tail +// calls to panic. + +// CHECK: tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E +// CHECK-SAME: !dbg ![[#first_dbg:]] +// CHECK: tail call void @_ZN4core9panicking5panic17h{{([0-9a-z]{16})}}E +// CHECK-SAME: !dbg ![[#second_dbg:]] + +// CHECK-DAG: ![[#func_dbg:]] = distinct !DISubprogram(name: "unwrap<i32>" +// CHECK-DAG: ![[#first_scope:]] = distinct !DILexicalBlock(scope: ![[#func_dbg]], +// CHECK: ![[#second_scope:]] = distinct !DILexicalBlock(scope: ![[#func_dbg]], +// CHECK: ![[#first_dbg]] = !DILocation(line: [[#]] +// CHECK-SAME: scope: ![[#first_scope]], inlinedAt: ![[#]]) +// CHECK: ![[#second_dbg]] = !DILocation(line: [[#]] +// CHECK-SAME: scope: ![[#second_scope]], inlinedAt: ![[#]]) + +#![crate_type = "lib"] + +#[no_mangle] +extern "C" fn add_numbers(x: &Option<i32>, y: &Option<i32>) -> i32 { + let x1 = x.unwrap(); + let y1 = y.unwrap(); + + x1 + y1 +} diff --git a/tests/codegen/issues/issue-115385-llvm-jump-threading.rs b/tests/codegen/issues/issue-115385-llvm-jump-threading.rs new file mode 100644 index 00000000000..142e3596d96 --- /dev/null +++ b/tests/codegen/issues/issue-115385-llvm-jump-threading.rs @@ -0,0 +1,46 @@ +// compile-flags: -O -Ccodegen-units=1 + +#![crate_type = "lib"] + +#[repr(i64)] +pub enum Boolean { + False = 0, + True = 1, +} + +impl Clone for Boolean { + fn clone(&self) -> Self { + *self + } +} + +impl Copy for Boolean {} + +extern "C" { + fn set_value(foo: *mut i64); + fn bar(); +} + +pub fn foo(x: bool) { + let mut foo = core::mem::MaybeUninit::<i64>::uninit(); + unsafe { + set_value(foo.as_mut_ptr()); + } + + if x { + let l1 = unsafe { *foo.as_mut_ptr().cast::<Boolean>() }; + if matches!(l1, Boolean::False) { + unsafe { + *foo.as_mut_ptr() = 0; + } + } + } + + let l2 = unsafe { *foo.as_mut_ptr() }; + if l2 == 2 { + // CHECK: call void @bar + unsafe { + bar(); + } + } +} diff --git a/tests/codegen/lib-optimizations/iter-sum.rs b/tests/codegen/lib-optimizations/iter-sum.rs new file mode 100644 index 00000000000..ff7ca6ef6c1 --- /dev/null +++ b/tests/codegen/lib-optimizations/iter-sum.rs @@ -0,0 +1,15 @@ +// ignore-debug: the debug assertions get in the way +// compile-flags: -O +// only-x86_64 (vectorization varies between architectures) +#![crate_type = "lib"] + + +// Ensure that slice + take + sum gets vectorized. +// Currently this relies on the slice::Iter::try_fold implementation +// CHECK-LABEL: @slice_take_sum +#[no_mangle] +pub fn slice_take_sum(s: &[u64], l: usize) -> u64 { + // CHECK: vector.body: + // CHECK: ret + s.iter().take(l).sum() +} diff --git a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs index 7555553c2c5..591ccd45ab6 100644 --- a/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs +++ b/tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs @@ -250,11 +250,11 @@ pub struct IntDoubleInt { c: i32, } -// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef dereferenceable(24) %a) +// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef align 8 dereferenceable(24) %a) #[no_mangle] pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {} -// CHECK: define void @f_ret_int_double_int_s(ptr noalias nocapture noundef sret(%IntDoubleInt) dereferenceable(24) %0) +// CHECK: define void @f_ret_int_double_int_s(ptr noalias nocapture noundef sret(%IntDoubleInt) align 8 dereferenceable(24) %_0) #[no_mangle] pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt { IntDoubleInt { a: 1, b: 2., c: 3 } diff --git a/tests/codegen/mem-replace-simple-type.rs b/tests/codegen/mem-replace-simple-type.rs index 174ac608e01..be3af989ef0 100644 --- a/tests/codegen/mem-replace-simple-type.rs +++ b/tests/codegen/mem-replace-simple-type.rs @@ -33,12 +33,21 @@ pub fn replace_ref_str<'a>(r: &mut &'a str, v: &'a str) -> &'a str { } #[no_mangle] -// CHECK-LABEL: @replace_short_array( -pub fn replace_short_array(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] { +// CHECK-LABEL: @replace_short_array_3( +pub fn replace_short_array_3(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] { // CHECK-NOT: alloca - // CHECK: %[[R:.+]] = load <3 x i32>, ptr %r, align 4 - // CHECK: store <3 x i32> %[[R]], ptr %result - // CHECK: %[[V:.+]] = load <3 x i32>, ptr %v, align 4 - // CHECK: store <3 x i32> %[[V]], ptr %r + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %result, ptr align 4 %r, i64 12, i1 false) + // CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %r, ptr align 4 %v, i64 12, i1 false) + std::mem::replace(r, v) +} + +#[no_mangle] +// CHECK-LABEL: @replace_short_array_4( +pub fn replace_short_array_4(r: &mut [u32; 4], v: [u32; 4]) -> [u32; 4] { + // CHECK-NOT: alloca + // CHECK: %[[R:.+]] = load <4 x i32>, ptr %r, align 4 + // CHECK: store <4 x i32> %[[R]], ptr %result + // CHECK: %[[V:.+]] = load <4 x i32>, ptr %v, align 4 + // CHECK: store <4 x i32> %[[V]], ptr %r std::mem::replace(r, v) } diff --git a/tests/codegen/move-before-nocapture-ref-arg.rs b/tests/codegen/move-before-nocapture-ref-arg.rs new file mode 100644 index 00000000000..c7b400c8f8d --- /dev/null +++ b/tests/codegen/move-before-nocapture-ref-arg.rs @@ -0,0 +1,22 @@ +// Verify that move before the call of the function with noalias, nocapture, readonly. +// #107436 +// compile-flags: -O +// min-llvm-version: 17 + +#![crate_type = "lib"] + +#[repr(C)] +pub struct ThreeSlices<'a>(&'a [u32], &'a [u32], &'a [u32]); + +#[no_mangle] +pub fn sum_slices(val: ThreeSlices) -> u32 { + // CHECK-NOT: memcpy + let val = val; + sum(&val) +} + +#[no_mangle] +#[inline(never)] +pub fn sum(val: &ThreeSlices) -> u32 { + val.0.iter().sum::<u32>() + val.1.iter().sum::<u32>() + val.2.iter().sum::<u32>() +} diff --git a/tests/codegen/repr/transparent.rs b/tests/codegen/repr/transparent.rs index b140fc719da..c5974248bb3 100644 --- a/tests/codegen/repr/transparent.rs +++ b/tests/codegen/repr/transparent.rs @@ -43,7 +43,6 @@ pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} } #[repr(transparent)] pub struct WithZeroSizedArray(*const f32, [i8; 0]); -// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever. // CHECK: define{{.*}}ptr @test_WithZeroSizedArray(ptr noundef %_1) #[no_mangle] pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} } diff --git a/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs new file mode 100644 index 00000000000..a70ef7751b6 --- /dev/null +++ b/tests/codegen/sanitizer/address-sanitizer-globals-tracking.rs @@ -0,0 +1,43 @@ +// Verifies that AddressSanitizer symbols show up as expected in LLVM IR with `-Zsanitizer`. +// This is a regression test for https://github.com/rust-lang/rust/issues/113404 +// +// Notes about the `compile-flags` below: +// +// * The original issue only reproed with LTO - this is why this angle has +// extra test coverage via different `revisions` +// * To observe the failure/repro at LLVM-IR level we need to use `staticlib` +// which necessitates `-C prefer-dynamic=false` - without the latter flag, +// we would have run into "cannot prefer dynamic linking when performing LTO". +// +// The test is restricted to `only-linux`, because the sanitizer-related instrumentation is target +// specific. In particular, `___asan_globals_registered` is only used in the +// `InstrumentGlobalsELF` and `InstrumentGlobalsMachO` code paths. The `only-linux` filter is +// narrower than really needed (i.e. narrower than ELF-or-MachO), but this seems ok - having a +// linux-only regression test should be sufficient here. +// +// needs-sanitizer-address +// only-linux +// +// revisions:ASAN ASAN-FAT-LTO +//[ASAN] compile-flags: -Zsanitizer=address +//[ASAN-FAT-LTO] compile-flags: -Zsanitizer=address -Cprefer-dynamic=false -Clto=fat + +#![crate_type="staticlib"] + +// The test below mimics `CACHED_POW10` from `library/core/src/num/flt2dec/strategy/grisu.rs` which +// (because of incorrect handling of `___asan_globals_registered` during LTO) was incorrectly +// reported as an ODR violation in https://crbug.com/1459233#c1. Before this bug was fixed, +// `___asan_globals_registered` would show up as `internal global i64` rather than `common hidden +// global i64`. (The test expectations ignore the exact type because on `arm-android` the type +// is `i32` rather than `i64`.) +// +// CHECK: @___asan_globals_registered = common hidden global +// CHECK: @__start_asan_globals = extern_weak hidden global +// CHECK: @__stop_asan_globals = extern_weak hidden global +#[no_mangle] +pub static CACHED_POW10: [(u64, i16, i16); 4] = [ + (0xe61acf033d1a45df, -1087, -308), + (0xab70fe17c79ac6ca, -1060, -300), + (0xff77b1fcbebcdc4f, -1034, -292), + (0xbe5691ef416bd60c, -1007, -284), +]; diff --git a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs index da608e180c5..2d8b13e2080 100644 --- a/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs +++ b/tests/codegen/sanitizer/cfi-emit-type-metadata-id-itanium-cxx-abi.rs @@ -500,12 +500,12 @@ pub fn foo149(_: Type14<Bar>, _: Type14<Bar>, _: Type14<Bar>) { } // CHECK: ![[TYPE45]] = !{i64 0, !"_ZTSFvu5usizeE"} // CHECK: ![[TYPE46]] = !{i64 0, !"_ZTSFvu5usizeS_E"} // CHECK: ![[TYPE47]] = !{i64 0, !"_ZTSFvu5usizeS_S_E"} -// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvu3f32E"} -// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvu3f32S_E"} -// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvu3f32S_S_E"} -// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvu3f64E"} -// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvu3f64S_E"} -// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvu3f64S_S_E"} +// CHECK: ![[TYPE48]] = !{i64 0, !"_ZTSFvfE"} +// CHECK: ![[TYPE49]] = !{i64 0, !"_ZTSFvffE"} +// CHECK: ![[TYPE50]] = !{i64 0, !"_ZTSFvfffE"} +// CHECK: ![[TYPE51]] = !{i64 0, !"_ZTSFvdE"} +// CHECK: ![[TYPE52]] = !{i64 0, !"_ZTSFvddE"} +// CHECK: ![[TYPE53]] = !{i64 0, !"_ZTSFvdddE"} // CHECK: ![[TYPE54]] = !{i64 0, !"_ZTSFvu4charE"} // CHECK: ![[TYPE55]] = !{i64 0, !"_ZTSFvu4charS_E"} // CHECK: ![[TYPE56]] = !{i64 0, !"_ZTSFvu4charS_S_E"} diff --git a/tests/codegen/slice-as_chunks.rs b/tests/codegen/slice-as_chunks.rs index 48e3f73fc86..efac9f3d68d 100644 --- a/tests/codegen/slice-as_chunks.rs +++ b/tests/codegen/slice-as_chunks.rs @@ -22,9 +22,9 @@ pub fn chunks4(x: &[u8]) -> &[[u8; 4]] { // CHECK-LABEL: @chunks4_with_remainder #[no_mangle] pub fn chunks4_with_remainder(x: &[u8]) -> (&[[u8; 4]], &[u8]) { - // CHECK: and i64 %x.1, -4 - // CHECK: and i64 %x.1, 3 - // CHECK: lshr exact + // CHECK-DAG: and i64 %x.1, -4 + // CHECK-DAG: and i64 %x.1, 3 + // CHECK-DAG: lshr // CHECK-NOT: mul // CHECK-NOT: udiv // CHECK-NOT: urem diff --git a/tests/codegen/slice-iter-nonnull.rs b/tests/codegen/slice-iter-nonnull.rs index f7d164bc856..8749226d401 100644 --- a/tests/codegen/slice-iter-nonnull.rs +++ b/tests/codegen/slice-iter-nonnull.rs @@ -100,13 +100,13 @@ pub fn slice_iter_is_empty(it: &std::slice::Iter<'_, u32>) -> bool { // CHECK-LABEL: @slice_iter_len #[no_mangle] pub fn slice_iter_len(it: &std::slice::Iter<'_, u32>) -> usize { - // CHECK: %[[START:.+]] = load ptr, ptr %it, - // CHECK-SAME: !nonnull - // CHECK-SAME: !noundef // CHECK: %[[ENDP:.+]] = getelementptr{{.+}}ptr %it,{{.+}} 1 // CHECK: %[[END:.+]] = load ptr, ptr %[[ENDP]] // CHECK-SAME: !nonnull // CHECK-SAME: !noundef + // CHECK: %[[START:.+]] = load ptr, ptr %it, + // CHECK-SAME: !nonnull + // CHECK-SAME: !noundef // CHECK: ptrtoint // CHECK: ptrtoint diff --git a/tests/codegen/sroa-fragment-debuginfo.rs b/tests/codegen/sroa-fragment-debuginfo.rs new file mode 100644 index 00000000000..fb10f63beaf --- /dev/null +++ b/tests/codegen/sroa-fragment-debuginfo.rs @@ -0,0 +1,46 @@ +// compile-flags: -g -Zmir-opt-level=0 -Zmir-enable-passes=+ScalarReplacementOfAggregates +// compile-flags: -Cno-prepopulate-passes +// +// Tested offsets are only correct for x86_64. +// only-x86_64 + +#![crate_type = "lib"] + +pub struct ExtraSlice<'input> { + slice: &'input [u8], + extra: u32, +} + +#[no_mangle] +pub fn extra(s: &[u8]) { +// CHECK: void @extra( +// CHECK: %slice.dbg.spill1 = alloca i32, +// CHECK: %slice.dbg.spill = alloca { ptr, i64 }, +// CHECK: %s.dbg.spill = alloca { ptr, i64 }, +// CHECK: call void @llvm.dbg.declare(metadata ptr %s.dbg.spill, metadata ![[S_EXTRA:.*]], metadata !DIExpression()), +// CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata ![[SLICE_EXTRA:.*]], metadata !DIExpression(DW_OP_LLVM_fragment, 0, 128)), +// CHECK: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill1, metadata ![[SLICE_EXTRA]], metadata !DIExpression(DW_OP_LLVM_fragment, 128, 32)), + let slice = ExtraSlice { slice: s, extra: s.len() as u32 }; +} + +struct Zst; + +pub struct ZstSlice<'input> { + slice: &'input [u8], + extra: Zst, +} + +#[no_mangle] +pub fn zst(s: &[u8]) { + // The field `extra` is a ZST. The fragment for the field `slice` encompasses the whole + // variable, so is not a fragment. In that case, the variable must have no fragment. + +// CHECK: void @zst( +// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %slice.dbg.spill, metadata !{}, metadata !DIExpression(DW_OP_LLVM_fragment, +// CHECK: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST:.*]], metadata !DIExpression()), +// CHECK-NOT: call void @llvm.dbg.declare(metadata ptr %{{.*}}, metadata ![[SLICE_ZST]], + let slice = ZstSlice { slice: s, extra: Zst }; +} + +// CHECK: ![[S_EXTRA]] = !DILocalVariable(name: "s", +// CHECK: ![[SLICE_EXTRA]] = !DILocalVariable(name: "slice", diff --git a/tests/codegen/swap-small-types.rs b/tests/codegen/swap-small-types.rs index 419645a3fc6..27bc00bc3ab 100644 --- a/tests/codegen/swap-small-types.rs +++ b/tests/codegen/swap-small-types.rs @@ -11,11 +11,12 @@ type RGB48 = [u16; 3]; // CHECK-LABEL: @swap_rgb48_manually( #[no_mangle] pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) { - // CHECK-NOT: alloca - // CHECK: %[[TEMP0:.+]] = load <3 x i16>, ptr %x, align 2 - // CHECK: %[[TEMP1:.+]] = load <3 x i16>, ptr %y, align 2 - // CHECK: store <3 x i16> %[[TEMP1]], ptr %x, align 2 - // CHECK: store <3 x i16> %[[TEMP0]], ptr %y, align 2 + // FIXME: See #115212 for why this has an alloca again + + // CHECK: alloca [3 x i16], align 2 + // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) + // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) + // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) let temp = *x; *x = *y; @@ -25,11 +26,25 @@ pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) { // CHECK-LABEL: @swap_rgb48 #[no_mangle] pub fn swap_rgb48(x: &mut RGB48, y: &mut RGB48) { + // FIXME: See #115212 for why this has an alloca again + + // CHECK: alloca [3 x i16], align 2 + // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) + // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) + // CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false) + swap(x, y) +} + +type RGBA64 = [u16; 4]; + +// CHECK-LABEL: @swap_rgba64 +#[no_mangle] +pub fn swap_rgba64(x: &mut RGBA64, y: &mut RGBA64) { // CHECK-NOT: alloca - // CHECK: load <3 x i16> - // CHECK: load <3 x i16> - // CHECK: store <3 x i16> - // CHECK: store <3 x i16> + // CHECK-DAG: %[[XVAL:.+]] = load <4 x i16>, ptr %x, align 2 + // CHECK-DAG: %[[YVAL:.+]] = load <4 x i16>, ptr %y, align 2 + // CHECK-DAG: store <4 x i16> %[[YVAL]], ptr %x, align 2 + // CHECK-DAG: store <4 x i16> %[[XVAL]], ptr %y, align 2 swap(x, y) } diff --git a/tests/codegen/tuple-layout-opt.rs b/tests/codegen/tuple-layout-opt.rs index 309fe1d5ec9..7cc67a9b51c 100644 --- a/tests/codegen/tuple-layout-opt.rs +++ b/tests/codegen/tuple-layout-opt.rs @@ -1,4 +1,3 @@ -// ignore-emscripten // compile-flags: -C no-prepopulate-passes -Copt-level=0 // Test that tuples get optimized layout, in particular with a ZST in the last field (#63244) |
