on s390x, use PassMode::Direct for vector types · rust-lang/rust@893d81f (original) (raw)

``

1

`` +

//! test that s390x vector types are passed using PassMode::Direct

``

``

2

`+

//! see also https://github.com/rust-lang/rust/issues/135744

`

``

3

`+

//@ add-core-stubs

`

``

4

`+

//@ compile-flags: --target s390x-unknown-linux-gnu -O

`

``

5

`+

//@ needs-llvm-components: systemz

`

``

6

+

``

7

`+

#![crate_type = "rlib"]

`

``

8

`+

#![feature(no_core, asm_experimental_arch)]

`

``

9

`+

#![feature(s390x_target_feature, simd_ffi, link_llvm_intrinsics, repr_simd)]

`

``

10

`+

#![no_core]

`

``

11

+

``

12

`+

extern crate minicore;

`

``

13

`+

use minicore::*;

`

``

14

+

``

15

`+

#[repr(simd)]

`

``

16

`+

struct i8x16([i8; 16]);

`

``

17

+

``

18

`+

#[repr(simd)]

`

``

19

`+

struct i16x8([i16; 8]);

`

``

20

+

``

21

`+

#[repr(simd)]

`

``

22

`+

struct i32x4([i32; 4]);

`

``

23

+

``

24

`+

#[repr(simd)]

`

``

25

`+

struct i64x2([i64; 2]);

`

``

26

+

``

27

`+

#[repr(simd)]

`

``

28

`+

struct f32x4([f32; 4]);

`

``

29

+

``

30

`+

#[repr(simd)]

`

``

31

`+

struct f64x2([f64; 2]);

`

``

32

+

``

33

`+

#[allow(improper_ctypes)]

`

``

34

`+

extern "C" {

`

``

35

`+

#[link_name = "llvm.smax.v16i8"]

`

``

36

`+

fn vmxb(a: i8x16, b: i8x16) -> i8x16;

`

``

37

`+

#[link_name = "llvm.smax.v8i16"]

`

``

38

`+

fn vmxh(a: i16x8, b: i16x8) -> i16x8;

`

``

39

`+

#[link_name = "llvm.smax.v4i32"]

`

``

40

`+

fn vmxf(a: i32x4, b: i32x4) -> i32x4;

`

``

41

`+

#[link_name = "llvm.smax.v2i64"]

`

``

42

`+

fn vmxg(a: i64x2, b: i64x2) -> i64x2;

`

``

43

`+

}

`

``

44

+

``

45

`+

// CHECK-LABEL: define <16 x i8> @max_i8x16

`

``

46

`+

// CHECK-SAME: <16 x i8> %a, <16 x i8> %b

`

``

47

`+

// CHECK: call <16 x i8> @llvm.smax.v16i8(<16 x i8> %a, <16 x i8> %b)

`

``

48

`+

#[no_mangle]

`

``

49

`+

#[target_feature(enable = "vector")]

`

``

50

`+

pub unsafe extern "C" fn max_i8x16(a: i8x16, b: i8x16) -> i8x16 {

`

``

51

`+

vmxb(a, b)

`

``

52

`+

}

`

``

53

+

``

54

`+

// CHECK-LABEL: define <8 x i16> @max_i16x8

`

``

55

`+

// CHECK-SAME: <8 x i16> %a, <8 x i16> %b

`

``

56

`+

// CHECK: call <8 x i16> @llvm.smax.v8i16(<8 x i16> %a, <8 x i16> %b)

`

``

57

`+

#[no_mangle]

`

``

58

`+

#[target_feature(enable = "vector")]

`

``

59

`+

pub unsafe extern "C" fn max_i16x8(a: i16x8, b: i16x8) -> i16x8 {

`

``

60

`+

vmxh(a, b)

`

``

61

`+

}

`

``

62

+

``

63

`+

// CHECK-LABEL: define <4 x i32> @max_i32x4

`

``

64

`+

// CHECK-SAME: <4 x i32> %a, <4 x i32> %b

`

``

65

`+

// CHECK: call <4 x i32> @llvm.smax.v4i32(<4 x i32> %a, <4 x i32> %b)

`

``

66

`+

#[no_mangle]

`

``

67

`+

#[target_feature(enable = "vector")]

`

``

68

`+

pub unsafe extern "C" fn max_i32x4(a: i32x4, b: i32x4) -> i32x4 {

`

``

69

`+

vmxf(a, b)

`

``

70

`+

}

`

``

71

+

``

72

`+

// CHECK-LABEL: define <2 x i64> @max_i64x2

`

``

73

`+

// CHECK-SAME: <2 x i64> %a, <2 x i64> %b

`

``

74

`+

// CHECK: call <2 x i64> @llvm.smax.v2i64(<2 x i64> %a, <2 x i64> %b)

`

``

75

`+

#[no_mangle]

`

``

76

`+

#[target_feature(enable = "vector")]

`

``

77

`+

pub unsafe extern "C" fn max_i64x2(a: i64x2, b: i64x2) -> i64x2 {

`

``

78

`+

vmxg(a, b)

`

``

79

`+

}

`

``

80

+

``

81

`+

// CHECK-LABEL: define <4 x float> @choose_f32x4

`

``

82

`+

// CHECK-SAME: <4 x float> %a, <4 x float> %b

`

``

83

`+

#[no_mangle]

`

``

84

`+

#[target_feature(enable = "vector")]

`

``

85

`+

pub unsafe extern "C" fn choose_f32x4(a: f32x4, b: f32x4, c: bool) -> f32x4 {

`

``

86

`+

if c { a } else { b }

`

``

87

`+

}

`

``

88

+

``

89

`+

// CHECK-LABEL: define <2 x double> @choose_f64x2

`

``

90

`+

// CHECK-SAME: <2 x double> %a, <2 x double> %b

`

``

91

`+

#[no_mangle]

`

``

92

`+

#[target_feature(enable = "vector")]

`

``

93

`+

pub unsafe extern "C" fn choose_f64x2(a: f64x2, b: f64x2, c: bool) -> f64x2 {

`

``

94

`+

if c { a } else { b }

`

``

95

`+

}

`

``

96

+

``

97

`+

#[repr(C)]

`

``

98

`+

struct Wrapper(T);

`

``

99

+

``

100

`+

#[no_mangle]

`

``

101

`+

#[inline(never)]

`

``

102

`+

#[target_feature(enable = "vector")]

`

``

103

`+

pub unsafe extern "C" fn max_wrapper_i8x16(a: Wrapper, b: Wrapper) -> Wrapper {

`

``

104

`+

// CHECK-LABEL: max_wrapper_i8x16

`

``

105

`+

// CHECK-SAME: sret([16 x i8])

`

``

106

`+

// CHECK-SAME: <16 x i8>

`

``

107

`+

// CHECK-SAME: <16 x i8>

`

``

108

`+

// CHECK: call <16 x i8> @llvm.smax.v16i8

`

``

109

`+

// CHECK-SAME: <16 x i8>

`

``

110

`+

// CHECK-SAME: <16 x i8>

`

``

111

`+

Wrapper(vmxb(a.0, b.0))

`

``

112

`+

}

`

``

113

+

``

114

`+

#[no_mangle]

`

``

115

`+

#[inline(never)]

`

``

116

`+

#[target_feature(enable = "vector")]

`

``

117

`+

pub unsafe extern "C" fn max_wrapper_i64x2(a: Wrapper, b: Wrapper) -> Wrapper {

`

``

118

`+

// CHECK-LABEL: max_wrapper_i64x2

`

``

119

`+

// CHECK-SAME: sret([16 x i8])

`

``

120

`+

// CHECK-SAME: <16 x i8>

`

``

121

`+

// CHECK-SAME: <16 x i8>

`

``

122

`+

// CHECK: call <2 x i64> @llvm.smax.v2i64

`

``

123

`+

// CHECK-SAME: <2 x i64>

`

``

124

`+

// CHECK-SAME: <2 x i64>

`

``

125

`+

Wrapper(vmxg(a.0, b.0))

`

``

126

`+

}

`

``

127

+

``

128

`+

#[no_mangle]

`

``

129

`+

#[inline(never)]

`

``

130

`+

#[target_feature(enable = "vector")]

`

``

131

`+

pub unsafe extern "C" fn choose_wrapper_f64x2(

`

``

132

`+

a: Wrapper,

`

``

133

`+

b: Wrapper,

`

``

134

`+

c: bool,

`

``

135

`+

) -> Wrapper {

`

``

136

`+

// CHECK-LABEL: choose_wrapper_f64x2

`

``

137

`+

// CHECK-SAME: sret([16 x i8])

`

``

138

`+

// CHECK-SAME: <16 x i8>

`

``

139

`+

// CHECK-SAME: <16 x i8>

`

``

140

`+

Wrapper(choose_f64x2(a.0, b.0, c))

`

``

141

`+

}

`

``

142

+

``

143

`+

// CHECK: declare <2 x i64> @llvm.smax.v2i64(<2 x i64>, <2 x i64>)

`