171 lines · plain
1; RUN: llc < %s -mtriple=x86_64-apple-darwin | FileCheck %s2 3define <4 x float> @foo(<4 x float> %val, <4 x float> %test) nounwind {4; CHECK-LABEL: LCPI0_0:5; CHECK-NEXT: .long 1065353216 ## 0x3f8000006; CHECK-NEXT: .long 1065353216 ## 0x3f8000007; CHECK-NEXT: .long 1065353216 ## 0x3f8000008; CHECK-NEXT: .long 1065353216 ## 0x3f8000009; CHECK-LABEL: foo:10; CHECK: ## %bb.0:11; CHECK-NEXT: cmpeqps %xmm1, %xmm012; CHECK-NEXT: andps {{.*}}(%rip), %xmm013; CHECK-NEXT: retq14 %cmp = fcmp oeq <4 x float> %val, %test15 %ext = zext <4 x i1> %cmp to <4 x i32>16 %result = sitofp <4 x i32> %ext to <4 x float>17 ret <4 x float> %result18}19 20; Make sure the operation doesn't try to get folded when the sizes don't match,21; as that ends up crashing later when trying to form a bitcast operation for22; the folded nodes.23define void @foo1(<4 x float> %val, <4 x float> %test, ptr %p) nounwind {24; CHECK-LABEL: LCPI1_0:25; CHECK-NEXT: .long 1 ## 0x126; CHECK-NEXT: .long 1 ## 0x127; CHECK-NEXT: .long 1 ## 0x128; CHECK-NEXT: .long 1 ## 0x129; CHECK-LABEL: foo1:30; CHECK: ## %bb.0:31; CHECK-NEXT: cmpeqps %xmm1, %xmm032; CHECK-NEXT: andps {{.*}}(%rip), %xmm033; CHECK-NEXT: pshufd {{.*#+}} xmm1 = xmm0[2,3,2,3]34; CHECK-NEXT: cvtdq2pd %xmm1, %xmm135; CHECK-NEXT: cvtdq2pd %xmm0, %xmm036; CHECK-NEXT: movaps %xmm0, (%rdi)37; CHECK-NEXT: movaps %xmm1, 16(%rdi)38; CHECK-NEXT: retq39 %cmp = fcmp oeq <4 x float> %val, %test40 %ext = zext <4 x i1> %cmp to <4 x i32>41 %result = sitofp <4 x i32> %ext to <4 x double>42 store <4 x double> %result, ptr %p43 ret void44}45 46; Also test the general purpose constant folding of int->fp.47define void @foo2(ptr noalias %result) nounwind {48; CHECK-LABEL: LCPI2_0:49; CHECK-NEXT: .long 0x40800000 ## float 450; CHECK-NEXT: .long 0x40a00000 ## float 551; CHECK-NEXT: .long 0x40c00000 ## float 652; CHECK-NEXT: .long 0x40e00000 ## float 753; CHECK-LABEL: foo2:54; CHECK: ## %bb.0:55; CHECK-NEXT: movaps {{.*#+}} xmm0 = [4.0E+0,5.0E+0,6.0E+0,7.0E+0]56; CHECK-NEXT: movaps %xmm0, (%rdi)57; CHECK-NEXT: retq58 %val = uitofp <4 x i32> <i32 4, i32 5, i32 6, i32 7> to <4 x float>59 store <4 x float> %val, ptr %result60 ret void61}62 63; Fold explicit AND operations when the constant isn't a splat of a single64; scalar value like what the zext creates.65define <4 x float> @foo3(<4 x float> %val, <4 x float> %test) nounwind {66; CHECK-LABEL: LCPI3_0:67; CHECK-NEXT: .long 1065353216 ## 0x3f80000068; CHECK-NEXT: .long 0 ## 0x069; CHECK-NEXT: .long 1065353216 ## 0x3f80000070; CHECK-NEXT: .long 0 ## 0x071; CHECK-LABEL: foo3:72; CHECK: ## %bb.0:73; CHECK-NEXT: cmpeqps %xmm1, %xmm074; CHECK-NEXT: andps {{.*}}(%rip), %xmm075; CHECK-NEXT: retq76 %cmp = fcmp oeq <4 x float> %val, %test77 %ext = zext <4 x i1> %cmp to <4 x i32>78 %and = and <4 x i32> %ext, <i32 255, i32 256, i32 257, i32 258>79 %result = sitofp <4 x i32> %and to <4 x float>80 ret <4 x float> %result81}82 83; Test the general purpose constant folding of uint->fp.84define void @foo4(ptr noalias %result) nounwind {85; CHECK-LABEL: LCPI4_0:86; CHECK-NEXT: .long 0x3f800000 ## float 187; CHECK-NEXT: .long 0x42fe0000 ## float 12788; CHECK-NEXT: .long 0x43000000 ## float 12889; CHECK-NEXT: .long 0x437f0000 ## float 25590; CHECK-LABEL: foo4:91; CHECK: ## %bb.0:92; CHECK-NEXT: movaps {{.*#+}} xmm0 = [1.0E+0,1.27E+2,1.28E+2,2.55E+2]93; CHECK-NEXT: movaps %xmm0, (%rdi)94; CHECK-NEXT: retq95 %val = uitofp <4 x i8> <i8 1, i8 127, i8 -128, i8 -1> to <4 x float>96 store <4 x float> %val, ptr %result97 ret void98}99 100; Test when we're masking against a sign extended setcc.101define <4 x float> @foo5(<4 x i32> %a0, <4 x i32> %a1) {102; CHECK-LABEL: LCPI5_0:103; CHECK-NEXT: .long 1065353216 ## 0x3f800000104; CHECK-NEXT: .long 0 ## 0x0105; CHECK-NEXT: .long 1065353216 ## 0x3f800000106; CHECK-NEXT: .long 0 ## 0x0107; CHECK: ## %bb.0:108; CHECK-NEXT: pcmpgtd %xmm1, %xmm0109; CHECK-NEXT: pand {{.*}}(%rip), %xmm0110; CHECK-NEXT: retq111 %1 = icmp sgt <4 x i32> %a0, %a1112 %2 = sext <4 x i1> %1 to <4 x i32>113 %3 = and <4 x i32> %2, <i32 1, i32 0, i32 1, i32 0>114 %4 = uitofp <4 x i32> %3 to <4 x float>115 ret <4 x float> %4116}117 118; Test when we're masking against mask arithmetic, not the setcc's directly.119define <4 x float> @foo6(<4 x i32> %a0, <4 x i32> %a1) {120; CHECK-LABEL: LCPI6_0:121; CHECK-NEXT: .long 1065353216 ## 0x3f800000122; CHECK-NEXT: .long 0 ## 0x0123; CHECK-NEXT: .long 1065353216 ## 0x3f800000124; CHECK-NEXT: .long 0 ## 0x0125; CHECK: ## %bb.0:126; CHECK-NEXT: movdqa %xmm0, %xmm2127; CHECK-NEXT: pcmpgtd %xmm1, %xmm2128; CHECK-NEXT: pxor %xmm1, %xmm1129; CHECK-NEXT: pcmpgtd %xmm1, %xmm0130; CHECK-NEXT: pand %xmm2, %xmm0131; CHECK-NEXT: pand {{.*}}(%rip), %xmm0132; CHECK-NEXT: retq133 %1 = icmp sgt <4 x i32> %a0, %a1134 %2 = icmp sgt <4 x i32> %a0, zeroinitializer135 %3 = and <4 x i1> %1, %2136 %4 = sext <4 x i1> %3 to <4 x i32>137 %5 = and <4 x i32> %4, <i32 1, i32 0, i32 1, i32 0>138 %6 = uitofp <4 x i32> %5 to <4 x float>139 ret <4 x float> %6140}141 142define <4 x float> @foo7(<4 x i64> %a) {143; CHECK-LABEL: LCPI7_0:144; CHECK-NEXT: .byte 0 ## 0x0145; CHECK-NEXT: .byte 255 ## 0xff146; CHECK-NEXT: .byte 0 ## 0x0147; CHECK-NEXT: .byte 0 ## 0x0148; CHECK-NEXT: .byte 0 ## 0x0149; CHECK-NEXT: .byte 255 ## 0xff150; CHECK-NEXT: .byte 0 ## 0x0151; CHECK-NEXT: .byte 0 ## 0x0152; CHECK-NEXT: .byte 0 ## 0x0153; CHECK-NEXT: .byte 255 ## 0xff154; CHECK-NEXT: .byte 0 ## 0x0155; CHECK-NEXT: .byte 0 ## 0x0156; CHECK-NEXT: .byte 0 ## 0x0157; CHECK-NEXT: .byte 255 ## 0xff158; CHECK-NEXT: .byte 0 ## 0x0159; CHECK-NEXT: .byte 0 ## 0x0160; CHECK-LABEL: foo7:161; CHECK: ## %bb.0:162; CHECK-NEXT: shufps {{.*#+}} xmm0 = xmm0[0,2],xmm1[0,2]163; CHECK-NEXT: andps {{.*}}(%rip), %xmm0164; CHECK-NEXT: cvtdq2ps %xmm0, %xmm0165; CHECK-NEXT: retq166 %b = and <4 x i64> %a, <i64 4278255360, i64 4278255360, i64 4278255360, i64 4278255360>167 %c = and <4 x i64> %b, <i64 65535, i64 65535, i64 65535, i64 65535>168 %d = uitofp <4 x i64> %c to <4 x float>169 ret <4 x float> %d170}171