// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 // 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 // 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 #include // // Test LLVM IR codegen of cmpXY instructions // // CHECK-LABEL: define dso_local <2 x double> @test_cmp_sd( // CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[A]], <2 x double> [[B]], i8 13) // CHECK-NEXT: ret <2 x double> [[TMP0]] // __m128d test_cmp_sd(__m128d a, __m128d b) { // Expects that the third argument in LLVM IR is immediate expression return _mm_cmp_sd(a, b, _CMP_GE_OS); } // CHECK-LABEL: define dso_local <4 x float> @test_cmp_ss( // CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[A]], <4 x float> [[B]], i8 13) // CHECK-NEXT: ret <4 x float> [[TMP0]] // __m128 test_cmp_ss(__m128 a, __m128 b) { // Expects that the third argument in LLVM IR is immediate expression return _mm_cmp_ss(a, b, _CMP_GE_OS); } // CHECK-LABEL: define dso_local <4 x float> @test_cmpgt_ss( // CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[B]], <4 x float> [[A]], i8 1) // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> [[TMP0]], <4 x i32> // CHECK-NEXT: ret <4 x float> [[SHUFFLE_I]] // __m128 test_cmpgt_ss(__m128 a, __m128 b) { return _mm_cmpgt_ss(a, b); } // CHECK-LABEL: define dso_local <4 x float> @test_cmpge_ss( // CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[B]], <4 x float> [[A]], i8 2) // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> [[TMP0]], <4 x i32> // CHECK-NEXT: ret <4 x float> [[SHUFFLE_I]] // __m128 test_cmpge_ss(__m128 a, __m128 b) { return _mm_cmpge_ss(a, b); } // CHECK-LABEL: define dso_local <4 x float> @test_cmpngt_ss( // CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[B]], <4 x float> [[A]], i8 5) // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> [[TMP0]], <4 x i32> // CHECK-NEXT: ret <4 x float> [[SHUFFLE_I]] // __m128 test_cmpngt_ss(__m128 a, __m128 b) { return _mm_cmpngt_ss(a, b); } // CHECK-LABEL: define dso_local <4 x float> @test_cmpnge_ss( // CHECK-SAME: <4 x float> noundef [[A:%.*]], <4 x float> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <4 x float> @llvm.x86.sse.cmp.ss(<4 x float> [[B]], <4 x float> [[A]], i8 6) // CHECK-NEXT: [[SHUFFLE_I:%.*]] = shufflevector <4 x float> [[A]], <4 x float> [[TMP0]], <4 x i32> // CHECK-NEXT: ret <4 x float> [[SHUFFLE_I]] // __m128 test_cmpnge_ss(__m128 a, __m128 b) { return _mm_cmpnge_ss(a, b); } // CHECK-LABEL: define dso_local <2 x double> @test_cmpgt_sd( // CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[B]], <2 x double> [[A]], i8 1) // CHECK-NEXT: [[VECEXT_I:%.*]] = extractelement <2 x double> [[TMP0]], i32 0 // CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[VECEXT_I]], i32 0 // CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <2 x double> [[A]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[VECEXT1_I]], i32 1 // CHECK-NEXT: ret <2 x double> [[VECINIT2_I]] // __m128d test_cmpgt_sd(__m128d a, __m128d b) { return _mm_cmpgt_sd(a, b); } // CHECK-LABEL: define dso_local <2 x double> @test_cmpge_sd( // CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[B]], <2 x double> [[A]], i8 2) // CHECK-NEXT: [[VECEXT_I:%.*]] = extractelement <2 x double> [[TMP0]], i32 0 // CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[VECEXT_I]], i32 0 // CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <2 x double> [[A]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[VECEXT1_I]], i32 1 // CHECK-NEXT: ret <2 x double> [[VECINIT2_I]] // __m128d test_cmpge_sd(__m128d a, __m128d b) { return _mm_cmpge_sd(a, b); } // CHECK-LABEL: define dso_local <2 x double> @test_cmpngt_sd( // CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[B]], <2 x double> [[A]], i8 5) // CHECK-NEXT: [[VECEXT_I:%.*]] = extractelement <2 x double> [[TMP0]], i32 0 // CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[VECEXT_I]], i32 0 // CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <2 x double> [[A]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[VECEXT1_I]], i32 1 // CHECK-NEXT: ret <2 x double> [[VECINIT2_I]] // __m128d test_cmpngt_sd(__m128d a, __m128d b) { return _mm_cmpngt_sd(a, b); } // CHECK-LABEL: define dso_local <2 x double> @test_cmpnge_sd( // CHECK-SAME: <2 x double> noundef [[A:%.*]], <2 x double> noundef [[B:%.*]]) #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[TMP0:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[B]], <2 x double> [[A]], i8 6) // CHECK-NEXT: [[VECEXT_I:%.*]] = extractelement <2 x double> [[TMP0]], i32 0 // CHECK-NEXT: [[VECINIT_I:%.*]] = insertelement <2 x double> poison, double [[VECEXT_I]], i32 0 // CHECK-NEXT: [[VECEXT1_I:%.*]] = extractelement <2 x double> [[A]], i32 1 // CHECK-NEXT: [[VECINIT2_I:%.*]] = insertelement <2 x double> [[VECINIT_I]], double [[VECEXT1_I]], i32 1 // CHECK-NEXT: ret <2 x double> [[VECINIT2_I]] // __m128d test_cmpnge_sd(__m128d a, __m128d b) { return _mm_cmpnge_sd(a, b); }