449 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -mtriple=x86_64-unknown-unknown -S | FileCheck %s3 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"5 6;7; DemandedBits - MOVMSK zeros the upper bits of the result.8;9 10define i32 @test_upper_x86_mmx_pmovmskb(<1 x i64> %a0) {11; CHECK-LABEL: @test_upper_x86_mmx_pmovmskb(12; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.x86.mmx.pmovmskb(<1 x i64> [[A0:%.*]])13; CHECK-NEXT: ret i32 [[TMP1]]14;15 %1 = call i32 @llvm.x86.mmx.pmovmskb(<1 x i64> %a0)16 %2 = and i32 %1, 25517 ret i32 %218}19 20define i32 @test_upper_x86_sse_movmsk_ps(<4 x float> %a0) {21; CHECK-LABEL: @test_upper_x86_sse_movmsk_ps(22; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x float> [[A0:%.*]] to <4 x i32>23; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <4 x i32> [[TMP1]], zeroinitializer24; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i1> [[TMP2]] to i425; CHECK-NEXT: [[TMP4:%.*]] = zext i4 [[TMP3]] to i3226; CHECK-NEXT: ret i32 [[TMP4]]27;28 %1 = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %a0)29 %2 = and i32 %1, 1530 ret i32 %231}32 33define i32 @test_upper_x86_sse2_movmsk_pd(<2 x double> %a0) {34; CHECK-LABEL: @test_upper_x86_sse2_movmsk_pd(35; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x double> [[A0:%.*]] to <2 x i64>36; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <2 x i64> [[TMP1]], zeroinitializer37; CHECK-NEXT: [[TMP3:%.*]] = bitcast <2 x i1> [[TMP2]] to i238; CHECK-NEXT: [[TMP4:%.*]] = zext i2 [[TMP3]] to i3239; CHECK-NEXT: ret i32 [[TMP4]]40;41 %1 = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> %a0)42 %2 = and i32 %1, 343 ret i32 %244}45 46define i32 @test_upper_x86_sse2_pmovmskb_128(<16 x i8> %a0) {47; CHECK-LABEL: @test_upper_x86_sse2_pmovmskb_128(48; CHECK-NEXT: [[TMP1:%.*]] = icmp slt <16 x i8> [[A0:%.*]], zeroinitializer49; CHECK-NEXT: [[TMP2:%.*]] = bitcast <16 x i1> [[TMP1]] to i1650; CHECK-NEXT: [[TMP3:%.*]] = zext i16 [[TMP2]] to i3251; CHECK-NEXT: ret i32 [[TMP3]]52;53 %1 = call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> %a0)54 %2 = and i32 %1, 6553555 ret i32 %256}57 58define i32 @test_upper_x86_avx_movmsk_ps_256(<8 x float> %a0) {59; CHECK-LABEL: @test_upper_x86_avx_movmsk_ps_256(60; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x float> [[A0:%.*]] to <8 x i32>61; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <8 x i32> [[TMP1]], zeroinitializer62; CHECK-NEXT: [[TMP3:%.*]] = bitcast <8 x i1> [[TMP2]] to i863; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP3]] to i3264; CHECK-NEXT: ret i32 [[TMP4]]65;66 %1 = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %a0)67 %2 = and i32 %1, 25568 ret i32 %269}70 71define i32 @test_upper_x86_avx_movmsk_pd_256(<4 x double> %a0) {72; CHECK-LABEL: @test_upper_x86_avx_movmsk_pd_256(73; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x double> [[A0:%.*]] to <4 x i64>74; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <4 x i64> [[TMP1]], zeroinitializer75; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i1> [[TMP2]] to i476; CHECK-NEXT: [[TMP4:%.*]] = zext i4 [[TMP3]] to i3277; CHECK-NEXT: ret i32 [[TMP4]]78;79 %1 = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> %a0)80 %2 = and i32 %1, 1581 ret i32 %282}83 84; llvm.x86.avx2.pmovmskb uses the whole of the 32-bit register.85 86;87; DemandedBits - If we don't use the lower bits then we just return zero.88;89 90define i32 @test_lower_x86_mmx_pmovmskb(<1 x i64> %a0) {91; CHECK-LABEL: @test_lower_x86_mmx_pmovmskb(92; CHECK-NEXT: ret i32 093;94 %1 = call i32 @llvm.x86.mmx.pmovmskb(<1 x i64> %a0)95 %2 = and i32 %1, -25696 ret i32 %297}98 99define i32 @test_lower_x86_sse_movmsk_ps(<4 x float> %a0) {100; CHECK-LABEL: @test_lower_x86_sse_movmsk_ps(101; CHECK-NEXT: ret i32 0102;103 %1 = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %a0)104 %2 = and i32 %1, -16105 ret i32 %2106}107 108define i32 @test_lower_x86_sse2_movmsk_pd(<2 x double> %a0) {109; CHECK-LABEL: @test_lower_x86_sse2_movmsk_pd(110; CHECK-NEXT: ret i32 0111;112 %1 = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> %a0)113 %2 = and i32 %1, -4114 ret i32 %2115}116 117define i32 @test_lower_x86_sse2_pmovmskb_128(<16 x i8> %a0) {118; CHECK-LABEL: @test_lower_x86_sse2_pmovmskb_128(119; CHECK-NEXT: ret i32 0120;121 %1 = call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> %a0)122 %2 = and i32 %1, -65536123 ret i32 %2124}125 126define i32 @test_lower_x86_avx_movmsk_ps_256(<8 x float> %a0) {127; CHECK-LABEL: @test_lower_x86_avx_movmsk_ps_256(128; CHECK-NEXT: ret i32 0129;130 %1 = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %a0)131 %2 = and i32 %1, -256132 ret i32 %2133}134 135define i32 @test_lower_x86_avx_movmsk_pd_256(<4 x double> %a0) {136; CHECK-LABEL: @test_lower_x86_avx_movmsk_pd_256(137; CHECK-NEXT: ret i32 0138;139 %1 = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> %a0)140 %2 = and i32 %1, -16141 ret i32 %2142}143 144; llvm.x86.avx2.pmovmskb uses the whole of the 32-bit register.145 146;147; Constant Folding (UNDEF -> ZERO)148;149 150define i32 @undef_x86_mmx_pmovmskb() {151; CHECK-LABEL: @undef_x86_mmx_pmovmskb(152; CHECK-NEXT: ret i32 0153;154 %1 = call i32 @llvm.x86.mmx.pmovmskb(<1 x i64> undef)155 ret i32 %1156}157 158define i32 @undef_x86_sse_movmsk_ps() {159; CHECK-LABEL: @undef_x86_sse_movmsk_ps(160; CHECK-NEXT: ret i32 0161;162 %1 = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> undef)163 ret i32 %1164}165 166define i32 @undef_x86_sse2_movmsk_pd() {167; CHECK-LABEL: @undef_x86_sse2_movmsk_pd(168; CHECK-NEXT: ret i32 0169;170 %1 = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> undef)171 ret i32 %1172}173 174define i32 @undef_x86_sse2_pmovmskb_128() {175; CHECK-LABEL: @undef_x86_sse2_pmovmskb_128(176; CHECK-NEXT: ret i32 0177;178 %1 = call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> undef)179 ret i32 %1180}181 182define i32 @undef_x86_avx_movmsk_ps_256() {183; CHECK-LABEL: @undef_x86_avx_movmsk_ps_256(184; CHECK-NEXT: ret i32 0185;186 %1 = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> undef)187 ret i32 %1188}189 190define i32 @undef_x86_avx_movmsk_pd_256() {191; CHECK-LABEL: @undef_x86_avx_movmsk_pd_256(192; CHECK-NEXT: ret i32 0193;194 %1 = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> undef)195 ret i32 %1196}197 198define i32 @undef_x86_avx2_pmovmskb() {199; CHECK-LABEL: @undef_x86_avx2_pmovmskb(200; CHECK-NEXT: ret i32 0201;202 %1 = call i32 @llvm.x86.avx2.pmovmskb(<32 x i8> undef)203 ret i32 %1204}205 206;207; Constant Folding (ZERO -> ZERO)208;209 210define i32 @zero_x86_sse_movmsk_ps() {211; CHECK-LABEL: @zero_x86_sse_movmsk_ps(212; CHECK-NEXT: ret i32 0213;214 %1 = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> zeroinitializer)215 ret i32 %1216}217 218define i32 @zero_x86_sse2_movmsk_pd() {219; CHECK-LABEL: @zero_x86_sse2_movmsk_pd(220; CHECK-NEXT: ret i32 0221;222 %1 = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> zeroinitializer)223 ret i32 %1224}225 226define i32 @zero_x86_sse2_pmovmskb_128() {227; CHECK-LABEL: @zero_x86_sse2_pmovmskb_128(228; CHECK-NEXT: ret i32 0229;230 %1 = call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> zeroinitializer)231 ret i32 %1232}233 234define i32 @zero_x86_avx_movmsk_ps_256() {235; CHECK-LABEL: @zero_x86_avx_movmsk_ps_256(236; CHECK-NEXT: ret i32 0237;238 %1 = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> zeroinitializer)239 ret i32 %1240}241 242define i32 @zero_x86_avx_movmsk_pd_256() {243; CHECK-LABEL: @zero_x86_avx_movmsk_pd_256(244; CHECK-NEXT: ret i32 0245;246 %1 = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> zeroinitializer)247 ret i32 %1248}249 250define i32 @zero_x86_avx2_pmovmskb() {251; CHECK-LABEL: @zero_x86_avx2_pmovmskb(252; CHECK-NEXT: ret i32 0253;254 %1 = call i32 @llvm.x86.avx2.pmovmskb(<32 x i8> zeroinitializer)255 ret i32 %1256}257 258;259; Constant Folding260;261 262define i32 @fold_x86_mmx_pmovmskb() {263; CHECK-LABEL: @fold_x86_mmx_pmovmskb(264; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.x86.mmx.pmovmskb(<1 x i64> splat (i64 18084223940296448))265; CHECK-NEXT: ret i32 [[TMP1]]266;267 %1 = bitcast <8 x i8> <i8 0, i8 255, i8 -1, i8 127, i8 -127, i8 63, i8 64, i8 256> to <1 x i64>268 %2 = call i32 @llvm.x86.mmx.pmovmskb(<1 x i64> %1)269 ret i32 %2270}271 272define i32 @fold_x86_sse_movmsk_ps() {273; CHECK-LABEL: @fold_x86_sse_movmsk_ps(274; CHECK-NEXT: ret i32 10275;276 %1 = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> <float 1.0, float -1.0, float 100.0, float -200.0>)277 ret i32 %1278}279 280define i32 @fold_x86_sse2_movmsk_pd() {281; CHECK-LABEL: @fold_x86_sse2_movmsk_pd(282; CHECK-NEXT: ret i32 2283;284 %1 = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> <double 1.0, double -1.0>)285 ret i32 %1286}287 288define i32 @fold_x86_sse2_pmovmskb_128() {289; CHECK-LABEL: @fold_x86_sse2_pmovmskb_128(290; CHECK-NEXT: ret i32 5654291;292 %1 = call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> <i8 0, i8 255, i8 -1, i8 127, i8 -127, i8 63, i8 64, i8 256, i8 0, i8 255, i8 -1, i8 127, i8 -127, i8 63, i8 64, i8 256>)293 ret i32 %1294}295 296define i32 @fold_x86_avx_movmsk_ps_256() {297; CHECK-LABEL: @fold_x86_avx_movmsk_ps_256(298; CHECK-NEXT: ret i32 170299;300 %1 = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> <float 1.0, float -1.0, float 100.0, float -200.0, float +0.0, float -0.0, float 100000.0, float -5000000.0>)301 ret i32 %1302}303 304define i32 @fold_x86_avx_movmsk_pd_256() {305; CHECK-LABEL: @fold_x86_avx_movmsk_pd_256(306; CHECK-NEXT: ret i32 10307;308 %1 = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> <double 1.0, double -1.0, double 100.0, double -200.0>)309 ret i32 %1310}311 312define i32 @fold_x86_avx2_pmovmskb() {313; CHECK-LABEL: @fold_x86_avx2_pmovmskb(314; CHECK-NEXT: ret i32 370546176315;316 %1 = call i32 @llvm.x86.avx2.pmovmskb(<32 x i8> <i8 0, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 undef, i8 0, i8 255, i8 -1, i8 127, i8 -127, i8 63, i8 64, i8 256, i8 0, i8 255, i8 -1, i8 127, i8 -127, i8 63, i8 64, i8 256, i8 0, i8 255, i8 -1, i8 127, i8 -127, i8 63, i8 64, i8 256>)317 ret i32 %1318}319 320define i32 @sext_sse_movmsk_ps(<4 x i1> %x) {321; CHECK-LABEL: @sext_sse_movmsk_ps(322; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4323; CHECK-NEXT: [[TMP2:%.*]] = zext i4 [[TMP1]] to i32324; CHECK-NEXT: ret i32 [[TMP2]]325;326 %sext = sext <4 x i1> %x to <4 x i32>327 %bc = bitcast <4 x i32> %sext to <4 x float>328 %r = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %bc)329 ret i32 %r330}331 332define i32 @sext_sse2_movmsk_pd(<2 x i1> %x) {333; CHECK-LABEL: @sext_sse2_movmsk_pd(334; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i1> [[X:%.*]] to i2335; CHECK-NEXT: [[TMP2:%.*]] = zext i2 [[TMP1]] to i32336; CHECK-NEXT: ret i32 [[TMP2]]337;338 %sext = sext <2 x i1> %x to <2 x i64>339 %bc = bitcast <2 x i64> %sext to <2 x double>340 %r = call i32 @llvm.x86.sse2.movmsk.pd(<2 x double> %bc)341 ret i32 %r342}343 344define i32 @sext_sse2_pmovmskb_128(<16 x i1> %x) {345; CHECK-LABEL: @sext_sse2_pmovmskb_128(346; CHECK-NEXT: [[TMP1:%.*]] = bitcast <16 x i1> [[X:%.*]] to i16347; CHECK-NEXT: [[TMP2:%.*]] = zext i16 [[TMP1]] to i32348; CHECK-NEXT: ret i32 [[TMP2]]349;350 %sext = sext <16 x i1> %x to <16 x i8>351 %r = call i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8> %sext)352 ret i32 %r353}354 355define i32 @sext_avx_movmsk_ps_256(<8 x i1> %x) {356; CHECK-LABEL: @sext_avx_movmsk_ps_256(357; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i1> [[X:%.*]] to i8358; CHECK-NEXT: [[TMP2:%.*]] = zext i8 [[TMP1]] to i32359; CHECK-NEXT: ret i32 [[TMP2]]360;361 %sext = sext <8 x i1> %x to <8 x i32>362 %bc = bitcast <8 x i32> %sext to <8 x float>363 %r = call i32 @llvm.x86.avx.movmsk.ps.256(<8 x float> %bc)364 ret i32 %r365}366 367define i32 @sext_avx_movmsk_pd_256(<4 x i1> %x) {368; CHECK-LABEL: @sext_avx_movmsk_pd_256(369; CHECK-NEXT: [[TMP1:%.*]] = bitcast <4 x i1> [[X:%.*]] to i4370; CHECK-NEXT: [[TMP2:%.*]] = zext i4 [[TMP1]] to i32371; CHECK-NEXT: ret i32 [[TMP2]]372;373 %sext = sext <4 x i1> %x to <4 x i64>374 %bc = bitcast <4 x i64> %sext to <4 x double>375 %r = call i32 @llvm.x86.avx.movmsk.pd.256(<4 x double> %bc)376 ret i32 %r377}378 379define i32 @sext_avx2_pmovmskb(<32 x i1> %x) {380; CHECK-LABEL: @sext_avx2_pmovmskb(381; CHECK-NEXT: [[TMP1:%.*]] = bitcast <32 x i1> [[X:%.*]] to i32382; CHECK-NEXT: ret i32 [[TMP1]]383;384 %sext = sext <32 x i1> %x to <32 x i8>385 %r = call i32 @llvm.x86.avx2.pmovmskb(<32 x i8> %sext)386 ret i32 %r387}388 389; Bitcast from sign-extended scalar.390 391define i32 @sext_sse_movmsk_ps_scalar_source(i1 %x) {392; CHECK-LABEL: @sext_sse_movmsk_ps_scalar_source(393; CHECK-NEXT: [[SEXT:%.*]] = sext i1 [[X:%.*]] to i128394; CHECK-NEXT: [[TMP1:%.*]] = bitcast i128 [[SEXT]] to <4 x i32>395; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <4 x i32> [[TMP1]], zeroinitializer396; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i1> [[TMP2]] to i4397; CHECK-NEXT: [[TMP4:%.*]] = zext i4 [[TMP3]] to i32398; CHECK-NEXT: ret i32 [[TMP4]]399;400 %sext = sext i1 %x to i128401 %bc = bitcast i128 %sext to <4 x float>402 %r = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %bc)403 ret i32 %r404}405 406; Bitcast from vector type with more elements.407 408define i32 @sext_sse_movmsk_ps_too_many_elts(<8 x i1> %x) {409; CHECK-LABEL: @sext_sse_movmsk_ps_too_many_elts(410; CHECK-NEXT: [[SEXT:%.*]] = sext <8 x i1> [[X:%.*]] to <8 x i16>411; CHECK-NEXT: [[TMP1:%.*]] = bitcast <8 x i16> [[SEXT]] to <4 x i32>412; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <4 x i32> [[TMP1]], zeroinitializer413; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i1> [[TMP2]] to i4414; CHECK-NEXT: [[TMP4:%.*]] = zext i4 [[TMP3]] to i32415; CHECK-NEXT: ret i32 [[TMP4]]416;417 %sext = sext <8 x i1> %x to <8 x i16>418 %bc = bitcast <8 x i16> %sext to <4 x float>419 %r = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %bc)420 ret i32 %r421}422 423; Handle this by doing a bitcasted sign-bit test after the sext.424 425define i32 @sext_sse_movmsk_ps_must_replicate_bits(<2 x i1> %x) {426; CHECK-LABEL: @sext_sse_movmsk_ps_must_replicate_bits(427; CHECK-NEXT: [[SEXT:%.*]] = sext <2 x i1> [[X:%.*]] to <2 x i64>428; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i64> [[SEXT]] to <4 x i32>429; CHECK-NEXT: [[TMP2:%.*]] = icmp slt <4 x i32> [[TMP1]], zeroinitializer430; CHECK-NEXT: [[TMP3:%.*]] = bitcast <4 x i1> [[TMP2]] to i4431; CHECK-NEXT: [[TMP4:%.*]] = zext i4 [[TMP3]] to i32432; CHECK-NEXT: ret i32 [[TMP4]]433;434 %sext = sext <2 x i1> %x to <2 x i64>435 %bc = bitcast <2 x i64> %sext to <4 x float>436 %r = call i32 @llvm.x86.sse.movmsk.ps(<4 x float> %bc)437 ret i32 %r438}439 440declare i32 @llvm.x86.mmx.pmovmskb(<1 x i64>)441 442declare i32 @llvm.x86.sse.movmsk.ps(<4 x float>)443declare i32 @llvm.x86.sse2.movmsk.pd(<2 x double>)444declare i32 @llvm.x86.sse2.pmovmskb.128(<16 x i8>)445 446declare i32 @llvm.x86.avx.movmsk.ps.256(<8 x float>)447declare i32 @llvm.x86.avx.movmsk.pd.256(<4 x double>)448declare i32 @llvm.x86.avx2.pmovmskb(<32 x i8>)449