170 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py2; RUN: llc < %s -mtriple=x86_64-apple-macosx10.6.6 -mattr=+sse4.1 | FileCheck %s3 4%0 = type { double }5%union.anon = type { float }6 7define i32 @double_signbit(double %d1) nounwind uwtable readnone ssp {8; CHECK-LABEL: double_signbit:9; CHECK: ## %bb.0: ## %entry10; CHECK-NEXT: movsd %xmm0, -{{[0-9]+}}(%rsp)11; CHECK-NEXT: movsd %xmm0, -{{[0-9]+}}(%rsp)12; CHECK-NEXT: movmskpd %xmm0, %eax13; CHECK-NEXT: andl $1, %eax14; CHECK-NEXT: retq15entry:16 %__x.addr.i = alloca double, align 817 %__u.i = alloca %0, align 818 store double %d1, ptr %__x.addr.i, align 819 store double %d1, ptr %__u.i, align 820 %tmp = bitcast double %d1 to i6421 %tmp1 = lshr i64 %tmp, 6322 %shr.i = trunc i64 %tmp1 to i3223 ret i32 %shr.i24}25 26define i32 @double_add_signbit(double %d1, double %d2) nounwind uwtable readnone ssp {27; CHECK-LABEL: double_add_signbit:28; CHECK: ## %bb.0: ## %entry29; CHECK-NEXT: addsd %xmm1, %xmm030; CHECK-NEXT: movsd %xmm0, -{{[0-9]+}}(%rsp)31; CHECK-NEXT: movsd %xmm0, -{{[0-9]+}}(%rsp)32; CHECK-NEXT: movmskpd %xmm0, %eax33; CHECK-NEXT: andl $1, %eax34; CHECK-NEXT: retq35entry:36 %__x.addr.i = alloca double, align 837 %__u.i = alloca %0, align 838 %add = fadd double %d1, %d239 store double %add, ptr %__x.addr.i, align 840 store double %add, ptr %__u.i, align 841 %tmp = bitcast double %add to i6442 %tmp1 = lshr i64 %tmp, 6343 %shr.i = trunc i64 %tmp1 to i3244 ret i32 %shr.i45}46 47define i32 @float_signbit(float %f1) nounwind uwtable readnone ssp {48; CHECK-LABEL: float_signbit:49; CHECK: ## %bb.0: ## %entry50; CHECK-NEXT: movss %xmm0, -{{[0-9]+}}(%rsp)51; CHECK-NEXT: movss %xmm0, -{{[0-9]+}}(%rsp)52; CHECK-NEXT: movmskps %xmm0, %eax53; CHECK-NEXT: andl $1, %eax54; CHECK-NEXT: retq55entry:56 %__x.addr.i = alloca float, align 457 %__u.i = alloca %union.anon, align 458 store float %f1, ptr %__x.addr.i, align 459 store float %f1, ptr %__u.i, align 460 %0 = bitcast float %f1 to i3261 %shr.i = lshr i32 %0, 3162 ret i32 %shr.i63}64 65define i32 @float_add_signbit(float %f1, float %f2) nounwind uwtable readnone ssp {66; CHECK-LABEL: float_add_signbit:67; CHECK: ## %bb.0: ## %entry68; CHECK-NEXT: addss %xmm1, %xmm069; CHECK-NEXT: movss %xmm0, -{{[0-9]+}}(%rsp)70; CHECK-NEXT: movss %xmm0, -{{[0-9]+}}(%rsp)71; CHECK-NEXT: movmskps %xmm0, %eax72; CHECK-NEXT: andl $1, %eax73; CHECK-NEXT: retq74entry:75 %__x.addr.i = alloca float, align 476 %__u.i = alloca %union.anon, align 477 %add = fadd float %f1, %f278 store float %add, ptr %__x.addr.i, align 479 store float %add, ptr %__u.i, align 480 %0 = bitcast float %add to i3281 %shr.i = lshr i32 %0, 3182 ret i32 %shr.i83}84 85; PR1157086define void @float_call_signbit(double %n) {87; CHECK-LABEL: float_call_signbit:88; CHECK: ## %bb.0: ## %entry89; CHECK-NEXT: movmskpd %xmm0, %edi90; CHECK-NEXT: andl $1, %edi91; CHECK-NEXT: jmp _float_call_signbit_callee ## TAILCALL92entry:93 %t0 = bitcast double %n to i6494 %tobool.i.i.i.i = icmp slt i64 %t0, 095 tail call void @float_call_signbit_callee(i1 zeroext %tobool.i.i.i.i)96 ret void97}98declare void @float_call_signbit_callee(i1 zeroext)99 100; Known zeros101define i32 @knownbits_v2f64(<2 x double> %x) {102; CHECK-LABEL: knownbits_v2f64:103; CHECK: ## %bb.0:104; CHECK-NEXT: movmskpd %xmm0, %eax105; CHECK-NEXT: retq106 %1 = tail call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> %x)107 %2 = and i32 %1, 3108 ret i32 %2109}110 111; Don't demand any movmsk signbits -> zero112define i32 @demandedbits_v16i8(<16 x i8> %x) {113; CHECK-LABEL: demandedbits_v16i8:114; CHECK: ## %bb.0:115; CHECK-NEXT: xorl %eax, %eax116; CHECK-NEXT: retq117 %1 = tail call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> %x)118 %2 = and i32 %1, 65536119 ret i32 %2120}121 122; Simplify demanded vector elts123define i32 @demandedelts_v4f32(<4 x float> %x) {124; CHECK-LABEL: demandedelts_v4f32:125; CHECK: ## %bb.0:126; CHECK-NEXT: movmskps %xmm0, %eax127; CHECK-NEXT: andl $1, %eax128; CHECK-NEXT: retq129 %1 = shufflevector <4 x float> %x, <4 x float> undef, <4 x i32> zeroinitializer130 %2 = tail call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %1)131 %3 = and i32 %2, 1132 ret i32 %3133}134 135; rdar://10247336136; movmskp{s|d} only set low 4/2 bits, high bits are known zero137 138define i32 @t1(<4 x float> %x, ptr nocapture %indexTable) nounwind uwtable readonly ssp {139; CHECK-LABEL: t1:140; CHECK: ## %bb.0: ## %entry141; CHECK-NEXT: movmskps %xmm0, %eax142; CHECK-NEXT: movl (%rdi,%rax,4), %eax143; CHECK-NEXT: retq144entry:145 %0 = tail call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %x) nounwind146 %idxprom = sext i32 %0 to i64147 %arrayidx = getelementptr inbounds i32, ptr %indexTable, i64 %idxprom148 %1 = load i32, ptr %arrayidx, align 4149 ret i32 %1150}151 152define i32 @t2(<4 x float> %x, ptr nocapture %indexTable) nounwind uwtable readonly ssp {153; CHECK-LABEL: t2:154; CHECK: ## %bb.0: ## %entry155; CHECK-NEXT: movmskpd %xmm0, %eax156; CHECK-NEXT: movl (%rdi,%rax,4), %eax157; CHECK-NEXT: retq158entry:159 %0 = bitcast <4 x float> %x to <2 x double>160 %1 = tail call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> %0) nounwind161 %idxprom = sext i32 %1 to i64162 %arrayidx = getelementptr inbounds i32, ptr %indexTable, i64 %idxprom163 %2 = load i32, ptr %arrayidx, align 4164 ret i32 %2165}166 167declare i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8>) nounwind readnone168declare i32 @llvm.x86.sse2.movmsk.pd(<2 x double>) nounwind readnone169declare i32 @llvm.x86.sse.movmsk.ps(<4 x float>) nounwind readnone170