Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 868330
Collapse All | Expand All

(-)a/compiler/rustc_codegen_llvm/src/common.rs (-2 / +1 lines)
Lines 109-116 impl<'ll> CodegenCx<'ll, '_> { Link Here
109
    pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
109
    pub fn const_get_elt(&self, v: &'ll Value, idx: u64) -> &'ll Value {
110
        unsafe {
110
        unsafe {
111
            assert_eq!(idx as c_uint as u64, idx);
111
            assert_eq!(idx as c_uint as u64, idx);
112
            let us = &[idx as c_uint];
112
            let r = llvm::LLVMGetAggregateElement(v, idx as c_uint).unwrap();
113
            let r = llvm::LLVMConstExtractValue(v, us.as_ptr(), us.len() as c_uint);
114
113
115
            debug!("const_get_elt(v={:?}, idx={}, r={:?})", v, idx, r);
114
            debug!("const_get_elt(v={:?}, idx={}, r={:?})", v, idx, r);
116
115
(-)a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs (-5 / +1 lines)
Lines 1134-1144 extern "C" { Link Here
1134
    pub fn LLVMConstIntToPtr<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
1134
    pub fn LLVMConstIntToPtr<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
1135
    pub fn LLVMConstBitCast<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
1135
    pub fn LLVMConstBitCast<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
1136
    pub fn LLVMConstPointerCast<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
1136
    pub fn LLVMConstPointerCast<'a>(ConstantVal: &'a Value, ToType: &'a Type) -> &'a Value;
1137
    pub fn LLVMConstExtractValue(
1137
    pub fn LLVMGetAggregateElement(ConstantVal: &Value, Idx: c_uint) -> Option<&Value>;
1138
        AggConstant: &Value,
1139
        IdxList: *const c_uint,
1140
        NumIdx: c_uint,
1141
    ) -> &Value;
1142
1138
1143
    // Operations on global variables, functions, and aliases (globals)
1139
    // Operations on global variables, functions, and aliases (globals)
1144
    pub fn LLVMIsDeclaration(Global: &Value) -> Bool;
1140
    pub fn LLVMIsDeclaration(Global: &Value) -> Bool;
(-)a/compiler/rustc_codegen_ssa/src/back/write.rs (-22 / +39 lines)
Lines 37-42 use rustc_target::spec::{MergeFunctions, SanitizerSet}; Link Here
37
use std::any::Any;
37
use std::any::Any;
38
use std::fs;
38
use std::fs;
39
use std::io;
39
use std::io;
40
use std::marker::PhantomData;
40
use std::mem;
41
use std::mem;
41
use std::path::{Path, PathBuf};
42
use std::path::{Path, PathBuf};
42
use std::str;
43
use std::str;
Lines 473-482 pub fn start_async_codegen<B: ExtraBackendMethods>( Link Here
473
        metadata_module,
474
        metadata_module,
474
        crate_info,
475
        crate_info,
475
476
476
        coordinator_send,
477
        codegen_worker_receive,
477
        codegen_worker_receive,
478
        shared_emitter_main,
478
        shared_emitter_main,
479
        future: coordinator_thread,
479
        coordinator: Coordinator {
480
            sender: coordinator_send,
481
            future: Some(coordinator_thread),
482
            phantom: PhantomData,
483
        },
480
        output_filenames: tcx.output_filenames(()).clone(),
484
        output_filenames: tcx.output_filenames(()).clone(),
481
    }
485
    }
482
}
486
}
Lines 1245-1250 fn start_executing_work<B: ExtraBackendMethods>( Link Here
1245
        // work to be done.
1249
        // work to be done.
1246
        while !codegen_done
1250
        while !codegen_done
1247
            || running > 0
1251
            || running > 0
1252
            || main_thread_worker_state == MainThreadWorkerState::LLVMing
1248
            || (!codegen_aborted
1253
            || (!codegen_aborted
1249
                && !(work_items.is_empty()
1254
                && !(work_items.is_empty()
1250
                    && needs_fat_lto.is_empty()
1255
                    && needs_fat_lto.is_empty()
Lines 1464-1470 fn start_executing_work<B: ExtraBackendMethods>( Link Here
1464
                    assert!(!codegen_aborted);
1469
                    assert!(!codegen_aborted);
1465
                    codegen_done = true;
1470
                    codegen_done = true;
1466
                    codegen_aborted = true;
1471
                    codegen_aborted = true;
1467
                    assert_eq!(main_thread_worker_state, MainThreadWorkerState::Codegenning);
1468
                }
1472
                }
1469
                Message::Done { result: Ok(compiled_module), worker_id } => {
1473
                Message::Done { result: Ok(compiled_module), worker_id } => {
1470
                    free_worker(worker_id);
1474
                    free_worker(worker_id);
Lines 1511-1516 fn start_executing_work<B: ExtraBackendMethods>( Link Here
1511
            }
1515
            }
1512
        }
1516
        }
1513
1517
1518
        if codegen_aborted {
1519
            return Err(());
1520
        }
1521
1514
        let needs_link = mem::take(&mut needs_link);
1522
        let needs_link = mem::take(&mut needs_link);
1515
        if !needs_link.is_empty() {
1523
        if !needs_link.is_empty() {
1516
            assert!(compiled_modules.is_empty());
1524
            assert!(compiled_modules.is_empty());
Lines 1800-1815 impl SharedEmitterMain { Link Here
1800
    }
1808
    }
1801
}
1809
}
1802
1810
1811
pub struct Coordinator<B: ExtraBackendMethods> {
1812
    pub sender: Sender<Box<dyn Any + Send>>,
1813
    future: Option<thread::JoinHandle<Result<CompiledModules, ()>>>,
1814
    // Only used for the Message type.
1815
    phantom: PhantomData<B>,
1816
}
1817
1818
impl<B: ExtraBackendMethods> Coordinator<B> {
1819
    fn join(mut self) -> std::thread::Result<Result<CompiledModules, ()>> {
1820
        self.future.take().unwrap().join()
1821
    }
1822
}
1823
1824
impl<B: ExtraBackendMethods> Drop for Coordinator<B> {
1825
    fn drop(&mut self) {
1826
        if let Some(future) = self.future.take() {
1827
            // If we haven't joined yet, signal to the coordinator that it should spawn no more
1828
            // work, and wait for worker threads to finish.
1829
            drop(self.sender.send(Box::new(Message::CodegenAborted::<B>)));
1830
            drop(future.join());
1831
        }
1832
    }
1833
}
1834
1803
pub struct OngoingCodegen<B: ExtraBackendMethods> {
1835
pub struct OngoingCodegen<B: ExtraBackendMethods> {
1804
    pub backend: B,
1836
    pub backend: B,
1805
    pub metadata: EncodedMetadata,
1837
    pub metadata: EncodedMetadata,
1806
    pub metadata_module: Option<CompiledModule>,
1838
    pub metadata_module: Option<CompiledModule>,
1807
    pub crate_info: CrateInfo,
1839
    pub crate_info: CrateInfo,
1808
    pub coordinator_send: Sender<Box<dyn Any + Send>>,
1809
    pub codegen_worker_receive: Receiver<Message<B>>,
1840
    pub codegen_worker_receive: Receiver<Message<B>>,
1810
    pub shared_emitter_main: SharedEmitterMain,
1841
    pub shared_emitter_main: SharedEmitterMain,
1811
    pub future: thread::JoinHandle<Result<CompiledModules, ()>>,
1812
    pub output_filenames: Arc<OutputFilenames>,
1842
    pub output_filenames: Arc<OutputFilenames>,
1843
    pub coordinator: Coordinator<B>,
1813
}
1844
}
1814
1845
1815
impl<B: ExtraBackendMethods> OngoingCodegen<B> {
1846
impl<B: ExtraBackendMethods> OngoingCodegen<B> {
Lines 1817-1824 impl<B: ExtraBackendMethods> OngoingCodegen<B> { Link Here
1817
        let _timer = sess.timer("finish_ongoing_codegen");
1848
        let _timer = sess.timer("finish_ongoing_codegen");
1818
1849
1819
        self.shared_emitter_main.check(sess, true);
1850
        self.shared_emitter_main.check(sess, true);
1820
        let future = self.future;
1851
        let compiled_modules = sess.time("join_worker_thread", || match self.coordinator.join() {
1821
        let compiled_modules = sess.time("join_worker_thread", || match future.join() {
1822
            Ok(Ok(compiled_modules)) => compiled_modules,
1852
            Ok(Ok(compiled_modules)) => compiled_modules,
1823
            Ok(Err(())) => {
1853
            Ok(Err(())) => {
1824
                sess.abort_if_errors();
1854
                sess.abort_if_errors();
Lines 1866-1891 impl<B: ExtraBackendMethods> OngoingCodegen<B> { Link Here
1866
1896
1867
        // These are generally cheap and won't throw off scheduling.
1897
        // These are generally cheap and won't throw off scheduling.
1868
        let cost = 0;
1898
        let cost = 0;
1869
        submit_codegened_module_to_llvm(&self.backend, &self.coordinator_send, module, cost);
1899
        submit_codegened_module_to_llvm(&self.backend, &self.coordinator.sender, module, cost);
1870
    }
1900
    }
1871
1901
1872
    pub fn codegen_finished(&self, tcx: TyCtxt<'_>) {
1902
    pub fn codegen_finished(&self, tcx: TyCtxt<'_>) {
1873
        self.wait_for_signal_to_codegen_item();
1903
        self.wait_for_signal_to_codegen_item();
1874
        self.check_for_errors(tcx.sess);
1904
        self.check_for_errors(tcx.sess);
1875
        drop(self.coordinator_send.send(Box::new(Message::CodegenComplete::<B>)));
1905
        drop(self.coordinator.sender.send(Box::new(Message::CodegenComplete::<B>)));
1876
    }
1877
1878
    /// Consumes this context indicating that codegen was entirely aborted, and
1879
    /// we need to exit as quickly as possible.
1880
    ///
1881
    /// This method blocks the current thread until all worker threads have
1882
    /// finished, and all worker threads should have exited or be real close to
1883
    /// exiting at this point.
1884
    pub fn codegen_aborted(self) {
1885
        // Signal to the coordinator it should spawn no more work and start
1886
        // shutdown.
1887
        drop(self.coordinator_send.send(Box::new(Message::CodegenAborted::<B>)));
1888
        drop(self.future.join());
1889
    }
1906
    }
1890
1907
1891
    pub fn check_for_errors(&self, sess: &Session) {
1908
    pub fn check_for_errors(&self, sess: &Session) {
(-)a/compiler/rustc_codegen_ssa/src/base.rs (-54 / +4 lines)
Lines 39-45 use rustc_target::abi::{Align, VariantIdx}; Link Here
39
39
40
use std::collections::BTreeSet;
40
use std::collections::BTreeSet;
41
use std::convert::TryFrom;
41
use std::convert::TryFrom;
42
use std::ops::{Deref, DerefMut};
43
use std::time::{Duration, Instant};
42
use std::time::{Duration, Instant};
44
43
45
use itertools::Itertools;
44
use itertools::Itertools;
Lines 583-589 pub fn codegen_crate<B: ExtraBackendMethods>( Link Here
583
        metadata_module,
582
        metadata_module,
584
        codegen_units.len(),
583
        codegen_units.len(),
585
    );
584
    );
586
    let ongoing_codegen = AbortCodegenOnDrop::<B>(Some(ongoing_codegen));
587
585
588
    // Codegen an allocator shim, if necessary.
586
    // Codegen an allocator shim, if necessary.
589
    //
587
    //
Lines 704-710 pub fn codegen_crate<B: ExtraBackendMethods>( Link Here
704
702
705
                submit_codegened_module_to_llvm(
703
                submit_codegened_module_to_llvm(
706
                    &backend,
704
                    &backend,
707
                    &ongoing_codegen.coordinator_send,
705
                    &ongoing_codegen.coordinator.sender,
708
                    module,
706
                    module,
709
                    cost,
707
                    cost,
710
                );
708
                );
Lines 714-720 pub fn codegen_crate<B: ExtraBackendMethods>( Link Here
714
                submit_pre_lto_module_to_llvm(
712
                submit_pre_lto_module_to_llvm(
715
                    &backend,
713
                    &backend,
716
                    tcx,
714
                    tcx,
717
                    &ongoing_codegen.coordinator_send,
715
                    &ongoing_codegen.coordinator.sender,
718
                    CachedModuleCodegen {
716
                    CachedModuleCodegen {
719
                        name: cgu.name().to_string(),
717
                        name: cgu.name().to_string(),
720
                        source: cgu.previous_work_product(tcx),
718
                        source: cgu.previous_work_product(tcx),
Lines 725-731 pub fn codegen_crate<B: ExtraBackendMethods>( Link Here
725
            CguReuse::PostLto => {
723
            CguReuse::PostLto => {
726
                submit_post_lto_module_to_llvm(
724
                submit_post_lto_module_to_llvm(
727
                    &backend,
725
                    &backend,
728
                    &ongoing_codegen.coordinator_send,
726
                    &ongoing_codegen.coordinator.sender,
729
                    CachedModuleCodegen {
727
                    CachedModuleCodegen {
730
                        name: cgu.name().to_string(),
728
                        name: cgu.name().to_string(),
731
                        source: cgu.previous_work_product(tcx),
729
                        source: cgu.previous_work_product(tcx),
Lines 752-806 pub fn codegen_crate<B: ExtraBackendMethods>( Link Here
752
    }
750
    }
753
751
754
    ongoing_codegen.check_for_errors(tcx.sess);
752
    ongoing_codegen.check_for_errors(tcx.sess);
755
753
    ongoing_codegen
756
    ongoing_codegen.into_inner()
757
}
758
759
/// A curious wrapper structure whose only purpose is to call `codegen_aborted`
760
/// when it's dropped abnormally.
761
///
762
/// In the process of working on rust-lang/rust#55238 a mysterious segfault was
763
/// stumbled upon. The segfault was never reproduced locally, but it was
764
/// suspected to be related to the fact that codegen worker threads were
765
/// sticking around by the time the main thread was exiting, causing issues.
766
///
767
/// This structure is an attempt to fix that issue where the `codegen_aborted`
768
/// message will block until all workers have finished. This should ensure that
769
/// even if the main codegen thread panics we'll wait for pending work to
770
/// complete before returning from the main thread, hopefully avoiding
771
/// segfaults.
772
///
773
/// If you see this comment in the code, then it means that this workaround
774
/// worked! We may yet one day track down the mysterious cause of that
775
/// segfault...
776
struct AbortCodegenOnDrop<B: ExtraBackendMethods>(Option<OngoingCodegen<B>>);
777
778
impl<B: ExtraBackendMethods> AbortCodegenOnDrop<B> {
779
    fn into_inner(mut self) -> OngoingCodegen<B> {
780
        self.0.take().unwrap()
781
    }
782
}
783
784
impl<B: ExtraBackendMethods> Deref for AbortCodegenOnDrop<B> {
785
    type Target = OngoingCodegen<B>;
786
787
    fn deref(&self) -> &OngoingCodegen<B> {
788
        self.0.as_ref().unwrap()
789
    }
790
}
791
792
impl<B: ExtraBackendMethods> DerefMut for AbortCodegenOnDrop<B> {
793
    fn deref_mut(&mut self) -> &mut OngoingCodegen<B> {
794
        self.0.as_mut().unwrap()
795
    }
796
}
797
798
impl<B: ExtraBackendMethods> Drop for AbortCodegenOnDrop<B> {
799
    fn drop(&mut self) {
800
        if let Some(codegen) = self.0.take() {
801
            codegen.codegen_aborted();
802
        }
803
    }
804
}
754
}
805
755
806
impl CrateInfo {
756
impl CrateInfo {
(-)a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp (+2 lines)
Lines 985-991 LLVMRustOptimizeWithNewPassManager( Link Here
985
    if (SanitizerOptions->SanitizeAddress) {
985
    if (SanitizerOptions->SanitizeAddress) {
986
      OptimizerLastEPCallbacks.push_back(
986
      OptimizerLastEPCallbacks.push_back(
987
        [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
987
        [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
988
#if LLVM_VERSION_LT(15, 0)
988
          MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
989
          MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
990
#endif
989
#if LLVM_VERSION_GE(14, 0)
991
#if LLVM_VERSION_GE(14, 0)
990
          AddressSanitizerOptions opts = AddressSanitizerOptions{
992
          AddressSanitizerOptions opts = AddressSanitizerOptions{
991
            /*CompileKernel=*/false,
993
            /*CompileKernel=*/false,
(-)a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp (+14 lines)
Lines 411-418 LLVMRustInlineAsm(LLVMTypeRef Ty, char *AsmString, size_t AsmStringLen, Link Here
411
411
412
extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
412
extern "C" bool LLVMRustInlineAsmVerify(LLVMTypeRef Ty, char *Constraints,
413
                                        size_t ConstraintsLen) {
413
                                        size_t ConstraintsLen) {
414
#if LLVM_VERSION_LT(15, 0)
414
  return InlineAsm::Verify(unwrap<FunctionType>(Ty),
415
  return InlineAsm::Verify(unwrap<FunctionType>(Ty),
415
                           StringRef(Constraints, ConstraintsLen));
416
                           StringRef(Constraints, ConstraintsLen));
417
#else
418
  // llvm::Error converts to true if it is an error.
419
  return !llvm::errorToBool(InlineAsm::verify(
420
      unwrap<FunctionType>(Ty), StringRef(Constraints, ConstraintsLen)));
421
#endif
416
}
422
}
417
423
418
extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
424
extern "C" void LLVMRustAppendModuleInlineAsm(LLVMModuleRef M, const char *Asm,
Lines 1865-1867 extern "C" void LLVMRustGetMangledName(LLVMValueRef V, RustStringRef Str) { Link Here
1865
  GlobalValue *GV = unwrap<GlobalValue>(V);
1871
  GlobalValue *GV = unwrap<GlobalValue>(V);
1866
  Mangler().getNameWithPrefix(OS, GV, true);
1872
  Mangler().getNameWithPrefix(OS, GV, true);
1867
}
1873
}
1874
1875
// LLVMGetAggregateElement was added in LLVM 15. For earlier LLVM versions just
1876
// use its implementation.
1877
#if LLVM_VERSION_LT(15, 0)
1878
extern "C" LLVMValueRef LLVMGetAggregateElement(LLVMValueRef C, unsigned Idx) {
1879
    return wrap(unwrap<Constant>(C)->getAggregateElement(Idx));
1880
}
1881
#endif
(-)a/src/test/codegen/function-arguments.rs (-7 lines)
Lines 215-224 pub fn enum_id_1(x: Option<Result<u16, u16>>) -> Option<Result<u16, u16>> { Link Here
215
pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
215
pub fn enum_id_2(x: Option<u8>) -> Option<u8> {
216
  x
216
  x
217
}
217
}
218
219
// CHECK: noalias {{i8\*|ptr}} @allocator()
220
#[no_mangle]
221
#[rustc_allocator]
222
pub fn allocator() -> *const i8 {
223
  std::ptr::null()
224
}
(-)a/src/test/codegen/repr-transparent-aggregates-2.rs (-8 / +8 lines)
Lines 37-55 pub enum TeBigS { Link Here
37
    Variant(BigS),
37
    Variant(BigS),
38
}
38
}
39
39
40
// CHECK: define void @test_BigS(%BigS* [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32]
40
// CHECK: define void @test_BigS({{%BigS\*|ptr}} [[BIGS_RET_ATTRS1:.*]] sret(%BigS) [[BIGS_RET_ATTRS2:.*]], [16 x i32]
41
#[no_mangle]
41
#[no_mangle]
42
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
42
pub extern fn test_BigS(_: BigS) -> BigS { loop {} }
43
43
44
// CHECK: define void @test_TsBigS(%TsBigS* [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
44
// CHECK: define void @test_TsBigS({{%TsBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TsBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
45
#[no_mangle]
45
#[no_mangle]
46
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
46
pub extern fn test_TsBigS(_: TsBigS) -> TsBigS { loop {} }
47
47
48
// CHECK: define void @test_TuBigS(%TuBigS* [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
48
// CHECK: define void @test_TuBigS({{%TuBigS\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%TuBigS) [[BIGS_RET_ATTRS2]], [16 x i32]
49
#[no_mangle]
49
#[no_mangle]
50
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
50
pub extern fn test_TuBigS(_: TuBigS) -> TuBigS { loop {} }
51
51
52
// CHECK: define void @test_TeBigS(%"TeBigS::Variant"* [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32]
52
// CHECK: define void @test_TeBigS({{%"TeBigS::Variant"\*|ptr}} [[BIGS_RET_ATTRS1]] sret(%"TeBigS::Variant") [[BIGS_RET_ATTRS2]], [16 x i32]
53
#[no_mangle]
53
#[no_mangle]
54
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
54
pub extern fn test_TeBigS(_: TeBigS) -> TeBigS { loop {} }
55
55
Lines 73-90 pub enum TeBigU { Link Here
73
    Variant(BigU),
73
    Variant(BigU),
74
}
74
}
75
75
76
// CHECK: define void @test_BigU(%BigU* [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32]
76
// CHECK: define void @test_BigU({{%BigU\*|ptr}} [[BIGU_RET_ATTRS1:.*]] sret(%BigU) [[BIGU_RET_ATTRS2:.*]], [16 x i32]
77
#[no_mangle]
77
#[no_mangle]
78
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
78
pub extern fn test_BigU(_: BigU) -> BigU { loop {} }
79
79
80
// CHECK: define void @test_TsBigU(%TsBigU* [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
80
// CHECK: define void @test_TsBigU({{%TsBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TsBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
81
#[no_mangle]
81
#[no_mangle]
82
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
82
pub extern fn test_TsBigU(_: TsBigU) -> TsBigU { loop {} }
83
83
84
// CHECK: define void @test_TuBigU(%TuBigU* [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
84
// CHECK: define void @test_TuBigU({{%TuBigU\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%TuBigU) [[BIGU_RET_ATTRS2]], [16 x i32]
85
#[no_mangle]
85
#[no_mangle]
86
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
86
pub extern fn test_TuBigU(_: TuBigU) -> TuBigU { loop {} }
87
87
88
// CHECK: define void @test_TeBigU(%"TeBigU::Variant"* [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32]
88
// CHECK: define void @test_TeBigU({{%"TeBigU::Variant"\*|ptr}} [[BIGU_RET_ATTRS1]] sret(%"TeBigU::Variant") [[BIGU_RET_ATTRS2]], [16 x i32]
89
#[no_mangle]
89
#[no_mangle]
90
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }
90
pub extern fn test_TeBigU(_: TeBigU) -> TeBigU { loop {} }

Return to bug 868330