/src/test/codegen/packed.rs

https://gitlab.com/jianglu/rust · Rust · 128 lines · 71 code · 19 blank · 38 comment · 0 complexity · 9cf0436af65862aaf572b46b5e4985dd MD5 · raw file

  1. // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
  2. // file at the top-level directory of this distribution and at
  3. // http://rust-lang.org/COPYRIGHT.
  4. //
  5. // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6. // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7. // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8. // option. This file may not be copied, modified, or distributed
  9. // except according to those terms.
  10. // compile-flags: -C no-prepopulate-passes
  11. #![crate_type = "lib"]
  12. #![feature(repr_packed)]
  13. #[repr(packed)]
  14. pub struct Packed1 {
  15. dealign: u8,
  16. data: u32
  17. }
  18. #[repr(packed(2))]
  19. pub struct Packed2 {
  20. dealign: u8,
  21. data: u32
  22. }
  23. // CHECK-LABEL: @write_pkd1
  24. #[no_mangle]
  25. pub fn write_pkd1(pkd: &mut Packed1) -> u32 {
  26. // CHECK: %{{.*}} = load i32, i32* %{{.*}}, align 1
  27. // CHECK: store i32 42, i32* %{{.*}}, align 1
  28. let result = pkd.data;
  29. pkd.data = 42;
  30. result
  31. }
  32. // CHECK-LABEL: @write_pkd2
  33. #[no_mangle]
  34. pub fn write_pkd2(pkd: &mut Packed2) -> u32 {
  35. // CHECK: %{{.*}} = load i32, i32* %{{.*}}, align 2
  36. // CHECK: store i32 42, i32* %{{.*}}, align 2
  37. let result = pkd.data;
  38. pkd.data = 42;
  39. result
  40. }
  41. pub struct Array([i32; 8]);
  42. #[repr(packed)]
  43. pub struct BigPacked1 {
  44. dealign: u8,
  45. data: Array
  46. }
  47. #[repr(packed(2))]
  48. pub struct BigPacked2 {
  49. dealign: u8,
  50. data: Array
  51. }
  52. // CHECK-LABEL: @call_pkd1
  53. #[no_mangle]
  54. pub fn call_pkd1(f: fn() -> Array) -> BigPacked1 {
  55. // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
  56. // CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
  57. // CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 32, i32 1, i1 false)
  58. // check that calls whose destination is a field of a packed struct
  59. // go through an alloca rather than calling the function with an
  60. // unaligned destination.
  61. BigPacked1 { dealign: 0, data: f() }
  62. }
  63. // CHECK-LABEL: @call_pkd2
  64. #[no_mangle]
  65. pub fn call_pkd2(f: fn() -> Array) -> BigPacked2 {
  66. // CHECK: [[ALLOCA:%[_a-z0-9]+]] = alloca %Array
  67. // CHECK: call void %{{.*}}(%Array* noalias nocapture sret dereferenceable(32) [[ALLOCA]])
  68. // CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 32, i32 2, i1 false)
  69. // check that calls whose destination is a field of a packed struct
  70. // go through an alloca rather than calling the function with an
  71. // unaligned destination.
  72. BigPacked2 { dealign: 0, data: f() }
  73. }
  74. #[repr(packed)]
  75. #[derive(Copy, Clone)]
  76. pub struct Packed1Pair(u8, u32);
  77. #[repr(packed(2))]
  78. #[derive(Copy, Clone)]
  79. pub struct Packed2Pair(u8, u32);
  80. // CHECK-LABEL: @pkd1_pair
  81. #[no_mangle]
  82. pub fn pkd1_pair(pair1: &mut Packed1Pair, pair2: &mut Packed1Pair) {
  83. // CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 5, i32 1, i1 false)
  84. *pair2 = *pair1;
  85. }
  86. // CHECK-LABEL: @pkd2_pair
  87. #[no_mangle]
  88. pub fn pkd2_pair(pair1: &mut Packed2Pair, pair2: &mut Packed2Pair) {
  89. // CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 6, i32 2, i1 false)
  90. *pair2 = *pair1;
  91. }
  92. #[repr(packed)]
  93. #[derive(Copy, Clone)]
  94. pub struct Packed1NestedPair((u32, u32));
  95. #[repr(packed(2))]
  96. #[derive(Copy, Clone)]
  97. pub struct Packed2NestedPair((u32, u32));
  98. // CHECK-LABEL: @pkd1_nested_pair
  99. #[no_mangle]
  100. pub fn pkd1_nested_pair(pair1: &mut Packed1NestedPair, pair2: &mut Packed1NestedPair) {
  101. // CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 8, i32 1, i1 false)
  102. *pair2 = *pair1;
  103. }
  104. // CHECK-LABEL: @pkd2_nested_pair
  105. #[no_mangle]
  106. pub fn pkd2_nested_pair(pair1: &mut Packed2NestedPair, pair2: &mut Packed2NestedPair) {
  107. // CHECK: call void @llvm.memcpy.{{.*}}(i8* %{{.*}}, i8* %{{.*}}, i{{[0-9]+}} 8, i32 2, i1 false)
  108. *pair2 = *pair1;
  109. }