|
1 |
| -// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -O3 -triple=x86_64-apple-darwin -target-feature +avx -emit-llvm -o - | FileCheck %s |
2 |
| -// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -O3 -triple=i386-apple-darwin -target-feature +avx -emit-llvm -o - | FileCheck %s |
3 |
| -// FIXME: The shufflevector instructions in test_cmpgt_sd are relying on O3 here. |
| 1 | +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 |
| 2 | +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-- -target-feature +avx -disable-O0-optnone -emit-llvm -o - | opt -S -passes=mem2reg | FileCheck %s |
| 3 | +// RUN: %clang_cc1 -flax-vector-conversions=none -ffreestanding %s -triple=i386-- -target-feature +avx -disable-O0-optnone -emit-llvm -o - | opt -S -passes=mem2reg | FileCheck %s |
4 | 4 |
|
5 | 5 |
|
6 | 6 | #include <immintrin.h>
|
|
9 | 9 | // Test LLVM IR codegen of cmpXY instructions
|
10 | 10 | //
|
11 | 11 |
|
| 12 | +// CHECK-LABEL: define dso_local <2 x double> @test_cmp_sd( |
| 13 | +// CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { |
| 14 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 15 | +// CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[A]], <2 x double> [[B]], i8 13) |
| 16 | +// CHECK-NEXT: ret <2 x double> [[TMP0]] |
| 17 | +// |
12 | 18 | __m128d test_cmp_sd(__m128d a, __m128d b) {
|
13 | 19 | // Expects that the third argument in LLVM IR is immediate expression
|
14 |
| - // CHECK: @llvm.x86.sse2.cmp.sd({{.*}}, i8 13) |
15 | 20 | return _mm_cmp_sd(a, b, _CMP_GE_OS);
|
16 | 21 | }
|
17 | 22 |
|
| 23 | +// CHECK-LABEL: define dso_local <4 x float> @test_cmp_ss( |
| 24 | +// CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { |
| 25 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 26 | +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[A]], <4 x float> [[B]], i8 13) |
| 27 | +// CHECK-NEXT: ret <4 x float> [[TMP0]] |
| 28 | +// |
18 | 29 | __m128 test_cmp_ss(__m128 a, __m128 b) {
|
19 | 30 | // Expects that the third argument in LLVM IR is immediate expression
|
20 |
| - // CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 13) |
21 | 31 | return _mm_cmp_ss(a, b, _CMP_GE_OS);
|
22 | 32 | }
|
23 | 33 |
|
| 34 | +// CHECK-LABEL: define dso_local <4 x float> @test_cmpgt_ss( |
| 35 | +// CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { |
| 36 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 37 | +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[B]], <4 x float> [[A]], i8 1) |
| 38 | +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> [[TMP0]], <4 x i32> <i32 4, i32 1, i32 2, i32 3> |
| 39 | +// CHECK-NEXT: ret <4 x float> [[SHUFFLE_I]] |
| 40 | +// |
24 | 41 | __m128 test_cmpgt_ss(__m128 a, __m128 b) {
|
25 |
| - // CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 1) |
26 |
| - // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 0, i32 5, i32 6, i32 7> |
27 | 42 | return _mm_cmpgt_ss(a, b);
|
28 | 43 | }
|
29 | 44 |
|
| 45 | +// CHECK-LABEL: define dso_local <4 x float> @test_cmpge_ss( |
| 46 | +// CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { |
| 47 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 48 | +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[B]], <4 x float> [[A]], i8 2) |
| 49 | +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> [[TMP0]], <4 x i32> <i32 4, i32 1, i32 2, i32 3> |
| 50 | +// CHECK-NEXT: ret <4 x float> [[SHUFFLE_I]] |
| 51 | +// |
30 | 52 | __m128 test_cmpge_ss(__m128 a, __m128 b) {
|
31 |
| - // CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 2) |
32 |
| - // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 0, i32 5, i32 6, i32 7> |
33 | 53 | return _mm_cmpge_ss(a, b);
|
34 | 54 | }
|
35 | 55 |
|
| 56 | +// CHECK-LABEL: define dso_local <4 x float> @test_cmpngt_ss( |
| 57 | +// CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { |
| 58 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 59 | +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[B]], <4 x float> [[A]], i8 5) |
| 60 | +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> [[TMP0]], <4 x i32> <i32 4, i32 1, i32 2, i32 3> |
| 61 | +// CHECK-NEXT: ret <4 x float> [[SHUFFLE_I]] |
| 62 | +// |
36 | 63 | __m128 test_cmpngt_ss(__m128 a, __m128 b) {
|
37 |
| - // CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 5) |
38 |
| - // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 0, i32 5, i32 6, i32 7> |
39 | 64 | return _mm_cmpngt_ss(a, b);
|
40 | 65 | }
|
41 | 66 |
|
| 67 | +// CHECK-LABEL: define dso_local <4 x float> @test_cmpnge_ss( |
| 68 | +// CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { |
| 69 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 70 | +// CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[B]], <4 x float> [[A]], i8 6) |
| 71 | +// CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> [[TMP0]], <4 x i32> <i32 4, i32 1, i32 2, i32 3> |
| 72 | +// CHECK-NEXT: ret <4 x float> [[SHUFFLE_I]] |
| 73 | +// |
42 | 74 | __m128 test_cmpnge_ss(__m128 a, __m128 b) {
|
43 |
| - // CHECK: @llvm.x86.sse.cmp.ss({{.*}}, i8 6) |
44 |
| - // CHECK: shufflevector <{{.*}}, <4 x i32> <i32 0, i32 5, i32 6, i32 7> |
45 | 75 | return _mm_cmpnge_ss(a, b);
|
46 | 76 | }
|
47 | 77 |
|
| 78 | +// CHECK-LABEL: define dso_local <2 x double> @test_cmpgt_sd( |
| 79 | +// CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0]] { |
| 80 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 81 | +// CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[B]], <2 x double> [[A]], i8 1) |
| 82 | +// CHECK-NEXT: [[VECEXT_I:%.*]] = extractelement <2 x double> [[TMP0]], i32 0 |
| 83 | +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[VECEXT_I]], i32 0 |
| 84 | +// CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <2 x double> [[A]], i32 1 |
| 85 | +// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[VECEXT1_I]], i32 1 |
| 86 | +// CHECK-NEXT: ret <2 x double> [[VECINIT2_I]] |
| 87 | +// |
48 | 88 | __m128d test_cmpgt_sd(__m128d a, __m128d b) {
|
49 |
| - // CHECK: @llvm.x86.sse2.cmp.sd({{.*}}, i8 1) |
50 |
| - // CHECK: shufflevector <{{.*}}, <2 x i32> <i32 0, i32 3> |
51 | 89 | return _mm_cmpgt_sd(a, b);
|
52 | 90 | }
|
53 | 91 |
|
| 92 | +// CHECK-LABEL: define dso_local <2 x double> @test_cmpge_sd( |
| 93 | +// CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0]] { |
| 94 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 95 | +// CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[B]], <2 x double> [[A]], i8 2) |
| 96 | +// CHECK-NEXT: [[VECEXT_I:%.*]] = extractelement <2 x double> [[TMP0]], i32 0 |
| 97 | +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[VECEXT_I]], i32 0 |
| 98 | +// CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <2 x double> [[A]], i32 1 |
| 99 | +// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[VECEXT1_I]], i32 1 |
| 100 | +// CHECK-NEXT: ret <2 x double> [[VECINIT2_I]] |
| 101 | +// |
54 | 102 | __m128d test_cmpge_sd(__m128d a, __m128d b) {
|
55 |
| - // CHECK: @llvm.x86.sse2.cmp.sd({{.*}}, i8 2) |
56 |
| - // CHECK: shufflevector <{{.*}}, <2 x i32> <i32 0, i32 3> |
57 | 103 | return _mm_cmpge_sd(a, b);
|
58 | 104 | }
|
59 | 105 |
|
| 106 | +// CHECK-LABEL: define dso_local <2 x double> @test_cmpngt_sd( |
| 107 | +// CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0]] { |
| 108 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 109 | +// CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[B]], <2 x double> [[A]], i8 5) |
| 110 | +// CHECK-NEXT: [[VECEXT_I:%.*]] = extractelement <2 x double> [[TMP0]], i32 0 |
| 111 | +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[VECEXT_I]], i32 0 |
| 112 | +// CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <2 x double> [[A]], i32 1 |
| 113 | +// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[VECEXT1_I]], i32 1 |
| 114 | +// CHECK-NEXT: ret <2 x double> [[VECINIT2_I]] |
| 115 | +// |
60 | 116 | __m128d test_cmpngt_sd(__m128d a, __m128d b) {
|
61 |
| - // CHECK: @llvm.x86.sse2.cmp.sd({{.*}}, i8 5) |
62 |
| - // CHECK: shufflevector <{{.*}}, <2 x i32> <i32 0, i32 3> |
63 | 117 | return _mm_cmpngt_sd(a, b);
|
64 | 118 | }
|
65 | 119 |
|
| 120 | +// CHECK-LABEL: define dso_local <2 x double> @test_cmpnge_sd( |
| 121 | +// CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0]] { |
| 122 | +// CHECK-NEXT: [[ENTRY:.*:]] |
| 123 | +// CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[B]], <2 x double> [[A]], i8 6) |
| 124 | +// CHECK-NEXT: [[VECEXT_I:%.*]] = extractelement <2 x double> [[TMP0]], i32 0 |
| 125 | +// CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[VECEXT_I]], i32 0 |
| 126 | +// CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <2 x double> [[A]], i32 1 |
| 127 | +// CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[VECEXT1_I]], i32 1 |
| 128 | +// CHECK-NEXT: ret <2 x double> [[VECINIT2_I]] |
| 129 | +// |
66 | 130 | __m128d test_cmpnge_sd(__m128d a, __m128d b) {
|
67 |
| - // CHECK: @llvm.x86.sse2.cmp.sd({{.*}}, i8 6) |
68 |
| - // CHECK: shufflevector <{{.*}}, <2 x i32> <i32 0, i32 3> |
69 | 131 | return _mm_cmpnge_sd(a, b);
|
70 | 132 | }
|
0 commit comments