
This reverts commit cf002847a464c004a57ca4777251b1aafc33d958 i.e., relands ba603b5e4d44f1a25207a2a00196471d2ba93424. It was reverted because it was subtly wrong: multiplying an uninitialized zero should not result in an initialized zero. This reland fixes the issue by using instrumentation analogous to visitAnd (bitwise AND of an initialized zero and an uninitialized value results in an initialized value). Additionally, this reland expands a test case; fixes the commit message; and optimizes the change to avoid the need for horizontalReduce. The current instrumentation has false positives: it does not take into account that multiplying an initialized zero value with an uninitialized value results in an initialized zero value This change fixes the issue during the multiplication step. The horizontal add step is modeled using bitwise OR. Future work can apply this improved handler to the AVX512 equivalent intrinsics (x86_avx512_pmaddw_d_512, x86_avx512_pmaddubs_w_512.) and AVX VNNI intrinsics.
1363 lines
73 KiB
LLVM
1363 lines
73 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt %s -S -passes=msan 2>&1 | FileCheck %s
|
|
;
|
|
; Handled strictly:
|
|
; - i32 @llvm.x86.sse2.movmsk.pd(<2 x double> %a0)
|
|
; - i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> %a0)
|
|
; - void @llvm.x86.sse2.pause()
|
|
; - void @llvm.x86.sse2.lfence()
|
|
; - void @llvm.x86.sse2.mfence()
|
|
; - void @llvm.x86.sse2.clflush(ptr %p)
|
|
|
|
target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
define <2 x double> @test_x86_sse2_cmp_pd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cmp_pd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <2 x i64> [[TMP3]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP5:%.*]] = sext <2 x i1> [[TMP4]] to <2 x i64>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.pd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]], i8 7)
|
|
; CHECK-NEXT: store <2 x i64> [[TMP5]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x double> [[RES]]
|
|
;
|
|
%res = call <2 x double> @llvm.x86.sse2.cmp.pd(<2 x double> %a0, <2 x double> %a1, i8 7) ; <<2 x double>> [#uses=1]
|
|
ret <2 x double> %res
|
|
}
|
|
declare <2 x double> @llvm.x86.sse2.cmp.pd(<2 x double>, <2 x double>, i8) nounwind readnone
|
|
|
|
|
|
define <2 x double> @test_x86_sse2_cmp_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cmp_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <2 x i64>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]], i8 7)
|
|
; CHECK-NEXT: store <2 x i64> [[TMP7]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x double> [[RES]]
|
|
;
|
|
%res = call <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double> %a0, <2 x double> %a1, i8 7) ; <<2 x double>> [#uses=1]
|
|
ret <2 x double> %res
|
|
}
|
|
declare <2 x double> @llvm.x86.sse2.cmp.sd(<2 x double>, <2 x double>, i8) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_comieq_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_comieq_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.comieq.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.comieq.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.comieq.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_comige_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_comige_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.comige.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.comige.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.comige.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_comigt_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_comigt_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.comigt.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.comigt.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.comigt.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_comile_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_comile_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.comile.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.comile.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.comile.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_comilt_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_comilt_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.comilt.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.comilt.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.comilt.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_comineq_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_comineq_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.comineq.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.comineq.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.comineq.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_cvtpd2dq(<2 x double> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtpd2dq(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double> %a0) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double>) nounwind readnone
|
|
|
|
|
|
define <2 x i64> @test_mm_cvtpd_epi32_zext(<2 x double> %a0) nounwind #0 {
|
|
; CHECK-LABEL: @test_mm_cvtpd_epi32_zext(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[CVT:%.*]] = call <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: [[RES:%.*]] = shufflevector <4 x i32> [[TMP4]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[RES1:%.*]] = shufflevector <4 x i32> [[CVT]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[BC:%.*]] = bitcast <4 x i32> [[RES]] to <2 x i64>
|
|
; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x i32> [[RES1]] to <2 x i64>
|
|
; CHECK-NEXT: store <2 x i64> [[BC]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[BC1]]
|
|
;
|
|
%cvt = call <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double> %a0)
|
|
%res = shufflevector <4 x i32> %cvt, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
%bc = bitcast <4 x i32> %res to <2 x i64>
|
|
ret <2 x i64> %bc
|
|
}
|
|
|
|
|
|
define <2 x i64> @test_mm_cvtpd_epi32_zext_load(ptr %p0) nounwind #0 {
|
|
; CHECK-LABEL: @test_mm_cvtpd_epi32_zext_load(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP2:%.*]], label [[TMP3:%.*]], !prof [[PROF1:![0-9]+]]
|
|
; CHECK: 2:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5:[0-9]+]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: [[A0:%.*]] = load <2 x double>, ptr [[P0:%.*]], align 16
|
|
; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[P0]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = xor i64 [[TMP4]], 87960930222080
|
|
; CHECK-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr
|
|
; CHECK-NEXT: [[_MSLD:%.*]] = load <2 x i64>, ptr [[TMP6]], align 16
|
|
; CHECK-NEXT: [[TMP7:%.*]] = icmp ne <2 x i64> [[_MSLD]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sext <2 x i1> [[TMP7]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <2 x i32> [[TMP8]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[CVT:%.*]] = call <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double> [[A0]])
|
|
; CHECK-NEXT: [[RES:%.*]] = shufflevector <4 x i32> [[TMP9]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[RES1:%.*]] = shufflevector <4 x i32> [[CVT]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[BC:%.*]] = bitcast <4 x i32> [[RES]] to <2 x i64>
|
|
; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x i32> [[RES1]] to <2 x i64>
|
|
; CHECK-NEXT: store <2 x i64> [[BC]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[BC1]]
|
|
;
|
|
%a0 = load <2 x double>, ptr %p0
|
|
%cvt = call <4 x i32> @llvm.x86.sse2.cvtpd2dq(<2 x double> %a0)
|
|
%res = shufflevector <4 x i32> %cvt, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
%bc = bitcast <4 x i32> %res to <2 x i64>
|
|
ret <2 x i64> %bc
|
|
}
|
|
|
|
|
|
define <4 x float> @test_x86_sse2_cvtpd2ps(<2 x double> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtpd2ps(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x float> @llvm.x86.sse2.cvtpd2ps(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x float> [[RES]]
|
|
;
|
|
%res = call <4 x float> @llvm.x86.sse2.cvtpd2ps(<2 x double> %a0) ; <<4 x float>> [#uses=1]
|
|
ret <4 x float> %res
|
|
}
|
|
declare <4 x float> @llvm.x86.sse2.cvtpd2ps(<2 x double>) nounwind readnone
|
|
|
|
define <4 x float> @test_x86_sse2_cvtpd2ps_zext(<2 x double> %a0) nounwind #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtpd2ps_zext(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[CVT:%.*]] = call <4 x float> @llvm.x86.sse2.cvtpd2ps(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: [[_MSPROP:%.*]] = shufflevector <4 x i32> [[TMP4]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[RES:%.*]] = shufflevector <4 x float> [[CVT]], <4 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: store <4 x i32> [[_MSPROP]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x float> [[RES]]
|
|
;
|
|
%cvt = call <4 x float> @llvm.x86.sse2.cvtpd2ps(<2 x double> %a0)
|
|
%res = shufflevector <4 x float> %cvt, <4 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
ret <4 x float> %res
|
|
}
|
|
|
|
define <4 x float> @test_x86_sse2_cvtpd2ps_zext_load(ptr %p0) nounwind #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtpd2ps_zext_load(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP2:%.*]], label [[TMP3:%.*]], !prof [[PROF1]]
|
|
; CHECK: 2:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: [[A0:%.*]] = load <2 x double>, ptr [[P0:%.*]], align 16
|
|
; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[P0]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = xor i64 [[TMP4]], 87960930222080
|
|
; CHECK-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr
|
|
; CHECK-NEXT: [[_MSLD:%.*]] = load <2 x i64>, ptr [[TMP6]], align 16
|
|
; CHECK-NEXT: [[TMP7:%.*]] = icmp ne <2 x i64> [[_MSLD]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sext <2 x i1> [[TMP7]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <2 x i32> [[TMP8]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[CVT:%.*]] = call <4 x float> @llvm.x86.sse2.cvtpd2ps(<2 x double> [[A0]])
|
|
; CHECK-NEXT: [[_MSPROP:%.*]] = shufflevector <4 x i32> [[TMP9]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[RES:%.*]] = shufflevector <4 x float> [[CVT]], <4 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: store <4 x i32> [[_MSPROP]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x float> [[RES]]
|
|
;
|
|
%a0 = load <2 x double>, ptr %p0
|
|
%cvt = call <4 x float> @llvm.x86.sse2.cvtpd2ps(<2 x double> %a0)
|
|
%res = shufflevector <4 x float> %cvt, <4 x float> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
ret <4 x float> %res
|
|
}
|
|
|
|
define <4 x i32> @test_x86_sse2_cvtps2dq(<4 x float> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtps2dq(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <4 x i32> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext <4 x i1> [[TMP2]] to <4 x i32>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float> [[A0:%.*]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float> %a0) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.cvtps2dq(<4 x float>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_cvtsd2si(<2 x double> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtsd2si(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x i64> [[TMP1]], i32 0
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP2]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.cvtsd2si(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.cvtsd2si(<2 x double> %a0) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.cvtsd2si(<2 x double>) nounwind readnone
|
|
|
|
|
|
define <4 x float> @test_x86_sse2_cvtsd2ss(<4 x float> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtsd2ss(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = extractelement <2 x i64> [[TMP1]], i32 0
|
|
; CHECK-NEXT: [[TMP4:%.*]] = insertelement <4 x i32> [[TMP2]], i32 0, i32 0
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP3]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP5:%.*]], label [[TMP6:%.*]], !prof [[PROF1]]
|
|
; CHECK: 5:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 6:
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x float> @llvm.x86.sse2.cvtsd2ss(<4 x float> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x float> [[RES]]
|
|
;
|
|
%res = call <4 x float> @llvm.x86.sse2.cvtsd2ss(<4 x float> %a0, <2 x double> %a1) ; <<4 x float>> [#uses=1]
|
|
ret <4 x float> %res
|
|
}
|
|
declare <4 x float> @llvm.x86.sse2.cvtsd2ss(<4 x float>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define <4 x float> @test_x86_sse2_cvtsd2ss_load(<4 x float> %a0, ptr %p1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtsd2ss_load(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: [[A1:%.*]] = load <2 x double>, ptr [[P1:%.*]], align 16
|
|
; CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[P1]] to i64
|
|
; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], 87960930222080
|
|
; CHECK-NEXT: [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr
|
|
; CHECK-NEXT: [[_MSLD:%.*]] = load <2 x i64>, ptr [[TMP7]], align 16
|
|
; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i64> [[_MSLD]], i32 0
|
|
; CHECK-NEXT: [[TMP9:%.*]] = insertelement <4 x i32> [[TMP2]], i32 0, i32 0
|
|
; CHECK-NEXT: [[_MSCMP1:%.*]] = icmp ne i64 [[TMP8]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP1]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF1]]
|
|
; CHECK: 10:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 11:
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x float> @llvm.x86.sse2.cvtsd2ss(<4 x float> [[A0:%.*]], <2 x double> [[A1]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x float> [[RES]]
|
|
;
|
|
%a1 = load <2 x double>, ptr %p1
|
|
%res = call <4 x float> @llvm.x86.sse2.cvtsd2ss(<4 x float> %a0, <2 x double> %a1) ; <<4 x float>> [#uses=1]
|
|
ret <4 x float> %res
|
|
}
|
|
|
|
|
|
define <4 x float> @test_x86_sse2_cvtsd2ss_load_optsize(<4 x float> %a0, ptr %p1) optsize #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvtsd2ss_load_optsize(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: [[A1:%.*]] = load <2 x double>, ptr [[P1:%.*]], align 16
|
|
; CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[P1]] to i64
|
|
; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], 87960930222080
|
|
; CHECK-NEXT: [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr
|
|
; CHECK-NEXT: [[_MSLD:%.*]] = load <2 x i64>, ptr [[TMP7]], align 16
|
|
; CHECK-NEXT: [[TMP8:%.*]] = extractelement <2 x i64> [[_MSLD]], i32 0
|
|
; CHECK-NEXT: [[TMP9:%.*]] = insertelement <4 x i32> [[TMP2]], i32 0, i32 0
|
|
; CHECK-NEXT: [[_MSCMP1:%.*]] = icmp ne i64 [[TMP8]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP1]], label [[TMP10:%.*]], label [[TMP11:%.*]], !prof [[PROF1]]
|
|
; CHECK: 10:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 11:
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x float> @llvm.x86.sse2.cvtsd2ss(<4 x float> [[A0:%.*]], <2 x double> [[A1]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x float> [[RES]]
|
|
;
|
|
%a1 = load <2 x double>, ptr %p1
|
|
%res = call <4 x float> @llvm.x86.sse2.cvtsd2ss(<4 x float> %a0, <2 x double> %a1) ; <<4 x float>> [#uses=1]
|
|
ret <4 x float> %res
|
|
}
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_cvttpd2dq(<2 x double> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvttpd2dq(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> %a0) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double>) nounwind readnone
|
|
|
|
|
|
define <2 x i64> @test_mm_cvttpd_epi32_zext(<2 x double> %a0) nounwind #0 {
|
|
; CHECK-LABEL: @test_mm_cvttpd_epi32_zext(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <2 x i64> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext <2 x i1> [[TMP2]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x i32> [[TMP3]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[CVT:%.*]] = call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: [[RES:%.*]] = shufflevector <4 x i32> [[TMP4]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[RES1:%.*]] = shufflevector <4 x i32> [[CVT]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[BC:%.*]] = bitcast <4 x i32> [[RES]] to <2 x i64>
|
|
; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x i32> [[RES1]] to <2 x i64>
|
|
; CHECK-NEXT: store <2 x i64> [[BC]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[BC1]]
|
|
;
|
|
%cvt = call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> %a0)
|
|
%res = shufflevector <4 x i32> %cvt, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
%bc = bitcast <4 x i32> %res to <2 x i64>
|
|
ret <2 x i64> %bc
|
|
}
|
|
|
|
|
|
define <2 x i64> @test_mm_cvttpd_epi32_zext_load(ptr %p0) nounwind #0 {
|
|
; CHECK-LABEL: @test_mm_cvttpd_epi32_zext_load(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP2:%.*]], label [[TMP3:%.*]], !prof [[PROF1]]
|
|
; CHECK: 2:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: [[A0:%.*]] = load <2 x double>, ptr [[P0:%.*]], align 16
|
|
; CHECK-NEXT: [[TMP4:%.*]] = ptrtoint ptr [[P0]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = xor i64 [[TMP4]], 87960930222080
|
|
; CHECK-NEXT: [[TMP6:%.*]] = inttoptr i64 [[TMP5]] to ptr
|
|
; CHECK-NEXT: [[_MSLD:%.*]] = load <2 x i64>, ptr [[TMP6]], align 16
|
|
; CHECK-NEXT: [[TMP7:%.*]] = icmp ne <2 x i64> [[_MSLD]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP8:%.*]] = sext <2 x i1> [[TMP7]] to <2 x i32>
|
|
; CHECK-NEXT: [[TMP9:%.*]] = shufflevector <2 x i32> [[TMP8]], <2 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 2, i32 3>
|
|
; CHECK-NEXT: [[CVT:%.*]] = call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> [[A0]])
|
|
; CHECK-NEXT: [[RES:%.*]] = shufflevector <4 x i32> [[TMP9]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[RES1:%.*]] = shufflevector <4 x i32> [[CVT]], <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
; CHECK-NEXT: [[BC:%.*]] = bitcast <4 x i32> [[RES]] to <2 x i64>
|
|
; CHECK-NEXT: [[BC1:%.*]] = bitcast <4 x i32> [[RES1]] to <2 x i64>
|
|
; CHECK-NEXT: store <2 x i64> [[BC]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[BC1]]
|
|
;
|
|
%a0 = load <2 x double>, ptr %p0
|
|
%cvt = call <4 x i32> @llvm.x86.sse2.cvttpd2dq(<2 x double> %a0)
|
|
%res = shufflevector <4 x i32> %cvt, <4 x i32> zeroinitializer, <4 x i32> <i32 0, i32 1, i32 4, i32 5>
|
|
%bc = bitcast <4 x i32> %res to <2 x i64>
|
|
ret <2 x i64> %bc
|
|
}
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_cvttps2dq(<4 x float> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvttps2dq(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ne <4 x i32> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP3:%.*]] = sext <4 x i1> [[TMP2]] to <4 x i32>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> [[A0:%.*]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> %a0) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_cvttsd2si(<2 x double> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_cvttsd2si(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = extractelement <2 x i64> [[TMP1]], i32 0
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP2]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.cvttsd2si(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.cvttsd2si(<2 x double> %a0) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.cvttsd2si(<2 x double>) nounwind readnone
|
|
|
|
|
|
define <2 x double> @test_x86_sse2_max_pd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_max_pd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse2.max.pd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store <2 x i64> [[_MSPROP]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x double> [[RES]]
|
|
;
|
|
%res = call <2 x double> @llvm.x86.sse2.max.pd(<2 x double> %a0, <2 x double> %a1) ; <<2 x double>> [#uses=1]
|
|
ret <2 x double> %res
|
|
}
|
|
declare <2 x double> @llvm.x86.sse2.max.pd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define <2 x double> @test_x86_sse2_max_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_max_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x i64> [[TMP1]], <2 x i64> [[TMP3]], <2 x i32> <i32 2, i32 1>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse2.max.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store <2 x i64> [[TMP4]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x double> [[RES]]
|
|
;
|
|
%res = call <2 x double> @llvm.x86.sse2.max.sd(<2 x double> %a0, <2 x double> %a1) ; <<2 x double>> [#uses=1]
|
|
ret <2 x double> %res
|
|
}
|
|
declare <2 x double> @llvm.x86.sse2.max.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define <2 x double> @test_x86_sse2_min_pd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_min_pd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse2.min.pd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store <2 x i64> [[_MSPROP]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x double> [[RES]]
|
|
;
|
|
%res = call <2 x double> @llvm.x86.sse2.min.pd(<2 x double> %a0, <2 x double> %a1) ; <<2 x double>> [#uses=1]
|
|
ret <2 x double> %res
|
|
}
|
|
declare <2 x double> @llvm.x86.sse2.min.pd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define <2 x double> @test_x86_sse2_min_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_min_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <2 x i64> [[TMP1]], <2 x i64> [[TMP3]], <2 x i32> <i32 2, i32 1>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x double> @llvm.x86.sse2.min.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store <2 x i64> [[TMP4]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x double> [[RES]]
|
|
;
|
|
%res = call <2 x double> @llvm.x86.sse2.min.sd(<2 x double> %a0, <2 x double> %a1) ; <<2 x double>> [#uses=1]
|
|
ret <2 x double> %res
|
|
}
|
|
declare <2 x double> @llvm.x86.sse2.min.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_movmsk_pd(<2 x double> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_movmsk_pd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = bitcast <2 x i64> [[TMP1]] to i128
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i128 [[TMP2]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> [[A0:%.*]])
|
|
; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> %a0) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.movmsk.pd(<2 x double>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_packssdw_128(<4 x i32> %a0, <4 x i32> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_packssdw_128(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <4 x i32> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP4:%.*]] = sext <4 x i1> [[TMP3]] to <4 x i32>
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne <4 x i32> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext <4 x i1> [[TMP5]] to <4 x i32>
|
|
; CHECK-NEXT: [[_MSPROP_VECTOR_PACK:%.*]] = call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> [[TMP4]], <4 x i32> [[TMP6]])
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]])
|
|
; CHECK-NEXT: store <8 x i16> [[_MSPROP_VECTOR_PACK]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> %a0, <4 x i32> %a1) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32>, <4 x i32>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_packssdw_128_fold() #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_packssdw_128_fold(
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP_VECTOR_PACK:%.*]] = call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> zeroinitializer, <4 x i32> zeroinitializer)
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> zeroinitializer, <4 x i32> <i32 65535, i32 65536, i32 -1, i32 -131072>)
|
|
; CHECK-NEXT: store <8 x i16> [[_MSPROP_VECTOR_PACK]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.packssdw.128(<4 x i32> zeroinitializer, <4 x i32> <i32 65535, i32 65536, i32 -1, i32 -131072>)
|
|
ret <8 x i16> %res
|
|
}
|
|
|
|
|
|
define <16 x i8> @test_x86_sse2_packsswb_128(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_packsswb_128(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <8 x i16> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP4:%.*]] = sext <8 x i1> [[TMP3]] to <8 x i16>
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne <8 x i16> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext <8 x i1> [[TMP5]] to <8 x i16>
|
|
; CHECK-NEXT: [[_MSPROP_VECTOR_PACK:%.*]] = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> [[TMP4]], <8 x i16> [[TMP6]])
|
|
; CHECK-NEXT: [[RES:%.*]] = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]])
|
|
; CHECK-NEXT: store <16 x i8> [[_MSPROP_VECTOR_PACK]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <16 x i8> [[RES]]
|
|
;
|
|
%res = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> %a0, <8 x i16> %a1) ; <<16 x i8>> [#uses=1]
|
|
ret <16 x i8> %res
|
|
}
|
|
declare <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define <16 x i8> @test_x86_sse2_packsswb_128_fold() #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_packsswb_128_fold(
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP_VECTOR_PACK:%.*]] = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> zeroinitializer, <8 x i16> zeroinitializer)
|
|
; CHECK-NEXT: [[RES:%.*]] = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> <i16 0, i16 255, i16 256, i16 -1, i16 -1, i16 -255, i16 -256, i16 -32678>, <8 x i16> zeroinitializer)
|
|
; CHECK-NEXT: store <16 x i8> [[_MSPROP_VECTOR_PACK]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <16 x i8> [[RES]]
|
|
;
|
|
%res = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> <i16 0, i16 255, i16 256, i16 65535, i16 -1, i16 -255, i16 -256, i16 -32678>, <8 x i16> zeroinitializer)
|
|
ret <16 x i8> %res
|
|
}
|
|
|
|
|
|
define <16 x i8> @test_x86_sse2_packuswb_128(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_packuswb_128(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = icmp ne <8 x i16> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP4:%.*]] = sext <8 x i1> [[TMP3]] to <8 x i16>
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne <8 x i16> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext <8 x i1> [[TMP5]] to <8 x i16>
|
|
; CHECK-NEXT: [[_MSPROP_VECTOR_PACK:%.*]] = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> [[TMP4]], <8 x i16> [[TMP6]])
|
|
; CHECK-NEXT: [[RES:%.*]] = call <16 x i8> @llvm.x86.sse2.packuswb.128(<8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]])
|
|
; CHECK-NEXT: store <16 x i8> [[_MSPROP_VECTOR_PACK]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <16 x i8> [[RES]]
|
|
;
|
|
%res = call <16 x i8> @llvm.x86.sse2.packuswb.128(<8 x i16> %a0, <8 x i16> %a1) ; <<16 x i8>> [#uses=1]
|
|
ret <16 x i8> %res
|
|
}
|
|
declare <16 x i8> @llvm.x86.sse2.packuswb.128(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define <16 x i8> @test_x86_sse2_packuswb_128_fold() #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_packuswb_128_fold(
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP_VECTOR_PACK:%.*]] = call <16 x i8> @llvm.x86.sse2.packsswb.128(<8 x i16> zeroinitializer, <8 x i16> zeroinitializer)
|
|
; CHECK-NEXT: [[RES:%.*]] = call <16 x i8> @llvm.x86.sse2.packuswb.128(<8 x i16> <i16 0, i16 255, i16 256, i16 -1, i16 -1, i16 -255, i16 -256, i16 -32678>, <8 x i16> zeroinitializer)
|
|
; CHECK-NEXT: store <16 x i8> [[_MSPROP_VECTOR_PACK]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <16 x i8> [[RES]]
|
|
;
|
|
%res = call <16 x i8> @llvm.x86.sse2.packuswb.128(<8 x i16> <i16 0, i16 255, i16 256, i16 65535, i16 -1, i16 -255, i16 -256, i16 -32678>, <8 x i16> zeroinitializer)
|
|
ret <16 x i8> %res
|
|
}
|
|
|
|
|
|
define <16 x i8> @test_x86_sse2_pavg_b(<16 x i8> %a0, <16 x i8> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pavg_b(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <16 x i8>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP:%.*]] = or <16 x i8> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <16 x i8> @llvm.x86.sse2.pavg.b(<16 x i8> [[A0:%.*]], <16 x i8> [[A1:%.*]])
|
|
; CHECK-NEXT: store <16 x i8> [[_MSPROP]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <16 x i8> [[RES]]
|
|
;
|
|
%res = call <16 x i8> @llvm.x86.sse2.pavg.b(<16 x i8> %a0, <16 x i8> %a1) ; <<16 x i8>> [#uses=1]
|
|
ret <16 x i8> %res
|
|
}
|
|
declare <16 x i8> @llvm.x86.sse2.pavg.b(<16 x i8>, <16 x i8>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_pavg_w(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pavg_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP:%.*]] = or <8 x i16> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]])
|
|
; CHECK-NEXT: store <8 x i16> [[_MSPROP]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.pavg.w(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_pmadd_wd(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pmadd_wd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <8 x i16> [[TMP1]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne <8 x i16> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP12:%.*]] = icmp ne <8 x i16> [[A0:%.*]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP13:%.*]] = icmp ne <8 x i16> [[A1:%.*]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP11:%.*]] = and <8 x i1> [[TMP4]], [[TMP5]]
|
|
; CHECK-NEXT: [[TMP14:%.*]] = and <8 x i1> [[TMP12]], [[TMP5]]
|
|
; CHECK-NEXT: [[TMP15:%.*]] = and <8 x i1> [[TMP4]], [[TMP13]]
|
|
; CHECK-NEXT: [[TMP16:%.*]] = or <8 x i1> [[TMP11]], [[TMP14]]
|
|
; CHECK-NEXT: [[TMP17:%.*]] = or <8 x i1> [[TMP16]], [[TMP15]]
|
|
; CHECK-NEXT: [[TMP7:%.*]] = sext <8 x i1> [[TMP17]] to <8 x i16>
|
|
; CHECK-NEXT: [[TMP18:%.*]] = bitcast <8 x i16> [[TMP7]] to <4 x i32>
|
|
; CHECK-NEXT: [[TMP19:%.*]] = icmp ne <4 x i32> [[TMP18]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext <4 x i1> [[TMP19]] to <4 x i32>
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> [[A0]], <8 x i16> [[A1]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16> %a0, <8 x i16> %a1) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.pmadd.wd(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_pmovmskb_128(<16 x i8> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pmovmskb_128(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i8> [[TMP1]] to i128
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i128 [[TMP2]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> [[A0:%.*]])
|
|
; CHECK-NEXT: store i32 0, ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> %a0) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_pmulh_w(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pmulh_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP:%.*]] = or <8 x i16> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]])
|
|
; CHECK-NEXT: store <8 x i16> [[_MSPROP]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.pmulh.w(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_pmulhu_w(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pmulhu_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSPROP:%.*]] = or <8 x i16> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.pmulhu.w(<8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]])
|
|
; CHECK-NEXT: store <8 x i16> [[_MSPROP]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.pmulhu.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.pmulhu.w(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define <2 x i64> @test_x86_sse2_psad_bw(<16 x i8> %a0, <16 x i8> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psad_bw(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <16 x i8>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <16 x i8>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <16 x i8> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = bitcast <16 x i8> [[TMP3]] to <2 x i64>
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne <2 x i64> [[TMP4]], zeroinitializer
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext <2 x i1> [[TMP5]] to <2 x i64>
|
|
; CHECK-NEXT: [[TMP7:%.*]] = lshr <2 x i64> [[TMP6]], splat (i64 48)
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @llvm.x86.sse2.psad.bw(<16 x i8> [[A0:%.*]], <16 x i8> [[A1:%.*]])
|
|
; CHECK-NEXT: store <2 x i64> [[TMP7]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[RES]]
|
|
;
|
|
%res = call <2 x i64> @llvm.x86.sse2.psad.bw(<16 x i8> %a0, <16 x i8> %a1) ; <<2 x i64>> [#uses=1]
|
|
ret <2 x i64> %res
|
|
}
|
|
declare <2 x i64> @llvm.x86.sse2.psad.bw(<16 x i8>, <16 x i8>) nounwind readnone
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_psll_d(<4 x i32> %a0, <4 x i32> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psll_d(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP3]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <4 x i32>
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call <4 x i32> @llvm.x86.sse2.psll.d(<4 x i32> [[TMP1]], <4 x i32> [[A1:%.*]])
|
|
; CHECK-NEXT: [[TMP9:%.*]] = or <4 x i32> [[TMP8]], [[TMP7]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.psll.d(<4 x i32> [[A0:%.*]], <4 x i32> [[A1]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.psll.d(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.psll.d(<4 x i32>, <4 x i32>) nounwind readnone
|
|
|
|
|
|
define <2 x i64> @test_x86_sse2_psll_q(<2 x i64> %a0, <2 x i64> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psll_q(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP3]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <2 x i64>
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> [[TMP1]], <2 x i64> [[A1:%.*]])
|
|
; CHECK-NEXT: [[TMP9:%.*]] = or <2 x i64> [[TMP8]], [[TMP7]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> [[A0:%.*]], <2 x i64> [[A1]])
|
|
; CHECK-NEXT: store <2 x i64> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[RES]]
|
|
;
|
|
%res = call <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64> %a0, <2 x i64> %a1) ; <<2 x i64>> [#uses=1]
|
|
ret <2 x i64> %res
|
|
}
|
|
declare <2 x i64> @llvm.x86.sse2.psll.q(<2 x i64>, <2 x i64>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_psll_w(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psll_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP3]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <8 x i16>
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call <8 x i16> @llvm.x86.sse2.psll.w(<8 x i16> [[TMP1]], <8 x i16> [[A1:%.*]])
|
|
; CHECK-NEXT: [[TMP9:%.*]] = or <8 x i16> [[TMP8]], [[TMP7]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.psll.w(<8 x i16> [[A0:%.*]], <8 x i16> [[A1]])
|
|
; CHECK-NEXT: store <8 x i16> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.psll.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.psll.w(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_pslli_d(<4 x i32> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pslli_d(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> [[TMP1]], i32 7)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> [[A0:%.*]], i32 7)
|
|
; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32> %a0, i32 7) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.pslli.d(<4 x i32>, i32) nounwind readnone
|
|
|
|
|
|
define <2 x i64> @test_x86_sse2_pslli_q(<2 x i64> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pslli_q(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> [[TMP1]], i32 7)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> [[A0:%.*]], i32 7)
|
|
; CHECK-NEXT: store <2 x i64> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[RES]]
|
|
;
|
|
%res = call <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64> %a0, i32 7) ; <<2 x i64>> [#uses=1]
|
|
ret <2 x i64> %res
|
|
}
|
|
declare <2 x i64> @llvm.x86.sse2.pslli.q(<2 x i64>, i32) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_pslli_w(<8 x i16> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pslli_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> [[TMP1]], i32 7)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <8 x i16> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> [[A0:%.*]], i32 7)
|
|
; CHECK-NEXT: store <8 x i16> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16> %a0, i32 7) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.pslli.w(<8 x i16>, i32) nounwind readnone
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_psra_d(<4 x i32> %a0, <4 x i32> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psra_d(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP3]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <4 x i32>
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call <4 x i32> @llvm.x86.sse2.psra.d(<4 x i32> [[TMP1]], <4 x i32> [[A1:%.*]])
|
|
; CHECK-NEXT: [[TMP9:%.*]] = or <4 x i32> [[TMP8]], [[TMP7]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.psra.d(<4 x i32> [[A0:%.*]], <4 x i32> [[A1]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.psra.d(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.psra.d(<4 x i32>, <4 x i32>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_psra_w(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psra_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP3]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <8 x i16>
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call <8 x i16> @llvm.x86.sse2.psra.w(<8 x i16> [[TMP1]], <8 x i16> [[A1:%.*]])
|
|
; CHECK-NEXT: [[TMP9:%.*]] = or <8 x i16> [[TMP8]], [[TMP7]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.psra.w(<8 x i16> [[A0:%.*]], <8 x i16> [[A1]])
|
|
; CHECK-NEXT: store <8 x i16> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.psra.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.psra.w(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_psrai_d(<4 x i32> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrai_d(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.x86.sse2.psrai.d(<4 x i32> [[TMP1]], i32 7)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.psrai.d(<4 x i32> [[A0:%.*]], i32 7)
|
|
; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.psrai.d(<4 x i32> %a0, i32 7) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.psrai.d(<4 x i32>, i32) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_psrai_w(<8 x i16> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrai_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.x86.sse2.psrai.w(<8 x i16> [[TMP1]], i32 7)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <8 x i16> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.psrai.w(<8 x i16> [[A0:%.*]], i32 7)
|
|
; CHECK-NEXT: store <8 x i16> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.psrai.w(<8 x i16> %a0, i32 7) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.psrai.w(<8 x i16>, i32) nounwind readnone
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_psrl_d(<4 x i32> %a0, <4 x i32> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrl_d(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <4 x i32>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i32> [[TMP2]] to i128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP3]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <4 x i32>
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call <4 x i32> @llvm.x86.sse2.psrl.d(<4 x i32> [[TMP1]], <4 x i32> [[A1:%.*]])
|
|
; CHECK-NEXT: [[TMP9:%.*]] = or <4 x i32> [[TMP8]], [[TMP7]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.psrl.d(<4 x i32> [[A0:%.*]], <4 x i32> [[A1]])
|
|
; CHECK-NEXT: store <4 x i32> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.psrl.d(<4 x i32> %a0, <4 x i32> %a1) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.psrl.d(<4 x i32>, <4 x i32>) nounwind readnone
|
|
|
|
|
|
define <2 x i64> @test_x86_sse2_psrl_q(<2 x i64> %a0, <2 x i64> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrl_q(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i64> [[TMP2]] to i128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP3]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <2 x i64>
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call <2 x i64> @llvm.x86.sse2.psrl.q(<2 x i64> [[TMP1]], <2 x i64> [[A1:%.*]])
|
|
; CHECK-NEXT: [[TMP9:%.*]] = or <2 x i64> [[TMP8]], [[TMP7]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @llvm.x86.sse2.psrl.q(<2 x i64> [[A0:%.*]], <2 x i64> [[A1]])
|
|
; CHECK-NEXT: store <2 x i64> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[RES]]
|
|
;
|
|
%res = call <2 x i64> @llvm.x86.sse2.psrl.q(<2 x i64> %a0, <2 x i64> %a1) ; <<2 x i64>> [#uses=1]
|
|
ret <2 x i64> %res
|
|
}
|
|
declare <2 x i64> @llvm.x86.sse2.psrl.q(<2 x i64>, <2 x i64>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_psrl_w(<8 x i16> %a0, <8 x i16> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrl_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i16> [[TMP2]] to i128
|
|
; CHECK-NEXT: [[TMP4:%.*]] = trunc i128 [[TMP3]] to i64
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i128
|
|
; CHECK-NEXT: [[TMP7:%.*]] = bitcast i128 [[TMP6]] to <8 x i16>
|
|
; CHECK-NEXT: [[TMP8:%.*]] = call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> [[TMP1]], <8 x i16> [[A1:%.*]])
|
|
; CHECK-NEXT: [[TMP9:%.*]] = or <8 x i16> [[TMP8]], [[TMP7]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> [[A0:%.*]], <8 x i16> [[A1]])
|
|
; CHECK-NEXT: store <8 x i16> [[TMP9]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16>, <8 x i16>) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_psrl_w_load(<8 x i16> %a0, ptr %p) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrl_w_load(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP3:%.*]], label [[TMP4:%.*]], !prof [[PROF1]]
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 4:
|
|
; CHECK-NEXT: [[A1:%.*]] = load <8 x i16>, ptr [[P:%.*]], align 16
|
|
; CHECK-NEXT: [[TMP5:%.*]] = ptrtoint ptr [[P]] to i64
|
|
; CHECK-NEXT: [[TMP6:%.*]] = xor i64 [[TMP5]], 87960930222080
|
|
; CHECK-NEXT: [[TMP7:%.*]] = inttoptr i64 [[TMP6]] to ptr
|
|
; CHECK-NEXT: [[_MSLD:%.*]] = load <8 x i16>, ptr [[TMP7]], align 16
|
|
; CHECK-NEXT: [[TMP8:%.*]] = bitcast <8 x i16> [[_MSLD]] to i128
|
|
; CHECK-NEXT: [[TMP9:%.*]] = trunc i128 [[TMP8]] to i64
|
|
; CHECK-NEXT: [[TMP10:%.*]] = icmp ne i64 [[TMP9]], 0
|
|
; CHECK-NEXT: [[TMP11:%.*]] = sext i1 [[TMP10]] to i128
|
|
; CHECK-NEXT: [[TMP12:%.*]] = bitcast i128 [[TMP11]] to <8 x i16>
|
|
; CHECK-NEXT: [[TMP13:%.*]] = call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> [[TMP2]], <8 x i16> [[A1]])
|
|
; CHECK-NEXT: [[TMP14:%.*]] = or <8 x i16> [[TMP13]], [[TMP12]]
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> [[A0:%.*]], <8 x i16> [[A1]])
|
|
; CHECK-NEXT: store <8 x i16> [[TMP14]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%a1 = load <8 x i16>, ptr %p
|
|
%res = call <8 x i16> @llvm.x86.sse2.psrl.w(<8 x i16> %a0, <8 x i16> %a1) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
|
|
|
|
define <4 x i32> @test_x86_sse2_psrli_d(<4 x i32> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrli_d(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> [[TMP1]], i32 7)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <4 x i32> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[RES:%.*]] = call <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> [[A0:%.*]], i32 7)
|
|
; CHECK-NEXT: store <4 x i32> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <4 x i32> [[RES]]
|
|
;
|
|
%res = call <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32> %a0, i32 7) ; <<4 x i32>> [#uses=1]
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.x86.sse2.psrli.d(<4 x i32>, i32) nounwind readnone
|
|
|
|
|
|
define <2 x i64> @test_x86_sse2_psrli_q(<2 x i64> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrli_q(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> [[TMP1]], i32 7)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[RES:%.*]] = call <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> [[A0:%.*]], i32 7)
|
|
; CHECK-NEXT: store <2 x i64> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <2 x i64> [[RES]]
|
|
;
|
|
%res = call <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64> %a0, i32 7) ; <<2 x i64>> [#uses=1]
|
|
ret <2 x i64> %res
|
|
}
|
|
declare <2 x i64> @llvm.x86.sse2.psrli.q(<2 x i64>, i32) nounwind readnone
|
|
|
|
|
|
define <8 x i16> @test_x86_sse2_psrli_w(<8 x i16> %a0) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_psrli_w(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i16>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP2:%.*]] = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> [[TMP1]], i32 7)
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <8 x i16> [[TMP2]], zeroinitializer
|
|
; CHECK-NEXT: [[RES:%.*]] = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> [[A0:%.*]], i32 7)
|
|
; CHECK-NEXT: store <8 x i16> [[TMP3]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret <8 x i16> [[RES]]
|
|
;
|
|
%res = call <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16> %a0, i32 7) ; <<8 x i16>> [#uses=1]
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.x86.sse2.psrli.w(<8 x i16>, i32) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_ucomieq_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_ucomieq_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.ucomieq.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.ucomieq.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.ucomieq.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_ucomige_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_ucomige_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.ucomige.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.ucomige.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.ucomige.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_ucomigt_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_ucomigt_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.ucomigt.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.ucomigt.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.ucomigt.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_ucomile_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_ucomile_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.ucomile.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.ucomile.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.ucomile.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_ucomilt_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_ucomilt_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.ucomilt.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.ucomilt.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.ucomilt.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
|
|
define i32 @test_x86_sse2_ucomineq_sd(<2 x double> %a0, <2 x double> %a1) #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_ucomineq_sd(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i64>, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: [[TMP2:%.*]] = load <2 x i64>, ptr inttoptr (i64 add (i64 ptrtoint (ptr @__msan_param_tls to i64), i64 16) to ptr), align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[TMP3:%.*]] = or <2 x i64> [[TMP1]], [[TMP2]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = extractelement <2 x i64> [[TMP3]], i64 0
|
|
; CHECK-NEXT: [[TMP5:%.*]] = icmp ne i64 [[TMP4]], 0
|
|
; CHECK-NEXT: [[TMP6:%.*]] = sext i1 [[TMP5]] to i32
|
|
; CHECK-NEXT: [[RES:%.*]] = call i32 @llvm.x86.sse2.ucomineq.sd(<2 x double> [[A0:%.*]], <2 x double> [[A1:%.*]])
|
|
; CHECK-NEXT: store i32 [[TMP6]], ptr @__msan_retval_tls, align 8
|
|
; CHECK-NEXT: ret i32 [[RES]]
|
|
;
|
|
%res = call i32 @llvm.x86.sse2.ucomineq.sd(<2 x double> %a0, <2 x double> %a1) ; <i32> [#uses=1]
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.x86.sse2.ucomineq.sd(<2 x double>, <2 x double>) nounwind readnone
|
|
|
|
define void @test_x86_sse2_pause() #0 {
|
|
; CHECK-LABEL: @test_x86_sse2_pause(
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: tail call void @llvm.x86.sse2.pause()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
tail call void @llvm.x86.sse2.pause()
|
|
ret void
|
|
}
|
|
declare void @llvm.x86.sse2.pause() nounwind
|
|
|
|
define void @lfence() nounwind #0 {
|
|
; CHECK-LABEL: @lfence(
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: tail call void @llvm.x86.sse2.lfence()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
tail call void @llvm.x86.sse2.lfence()
|
|
ret void
|
|
}
|
|
declare void @llvm.x86.sse2.lfence() nounwind
|
|
|
|
define void @mfence() nounwind #0 {
|
|
; CHECK-LABEL: @mfence(
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: tail call void @llvm.x86.sse2.mfence()
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
tail call void @llvm.x86.sse2.mfence()
|
|
ret void
|
|
}
|
|
declare void @llvm.x86.sse2.mfence() nounwind
|
|
|
|
define void @clflush(ptr %p) nounwind #0 {
|
|
; CHECK-LABEL: @clflush(
|
|
; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr @__msan_param_tls, align 8
|
|
; CHECK-NEXT: call void @llvm.donothing()
|
|
; CHECK-NEXT: [[_MSCMP:%.*]] = icmp ne i64 [[TMP1]], 0
|
|
; CHECK-NEXT: br i1 [[_MSCMP]], label [[TMP2:%.*]], label [[TMP3:%.*]], !prof [[PROF1]]
|
|
; CHECK: 2:
|
|
; CHECK-NEXT: call void @__msan_warning_noreturn() #[[ATTR5]]
|
|
; CHECK-NEXT: unreachable
|
|
; CHECK: 3:
|
|
; CHECK-NEXT: tail call void @llvm.x86.sse2.clflush(ptr [[P:%.*]])
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
tail call void @llvm.x86.sse2.clflush(ptr %p)
|
|
ret void
|
|
}
|
|
declare void @llvm.x86.sse2.clflush(ptr) nounwind
|
|
|
|
attributes #0 = { sanitize_memory }
|