llvm.org GIT mirror llvm / 44cfbc7
[InstCombine] allow SimplifyDemandedVectorElts to work with FP binops We're a long way from D50992 and D51553, but this is where we have to start. We weren't back-propagating undefs into binop constant values for anything but add/sub/mul/and/or/xor. This is likely because we have to be careful about not introducing UB/poison with div/rem/shift. But I suspect we already are getting the poison part wrong for add/sub/mul (although it may not be possible to expose the bug currently because we use SimplifyDemandedVectorElts from a limited set of opcodes). See the discussion/implementation from D48987 and D49047. This patch just enables functionality for FP ops because those do not have UB/poison potential. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@343727 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjay Patel 1 year, 9 months ago
5 changed file(s) with 36 addition(s) and 34 deletion(s). Raw diff Collapse all Expand all
13771377 }
13781378 break;
13791379 }
1380 case Instruction::And:
1381 case Instruction::Or:
1382 case Instruction::Xor:
1383 case Instruction::Add:
1384 case Instruction::Sub:
1385 case Instruction::Mul:
1386 // div/rem demand all inputs, because they don't want divide by zero.
1387 TmpV = SimplifyDemandedVectorElts(I->getOperand(0), DemandedElts, UndefElts,
1388 Depth + 1);
1389 if (TmpV) { I->setOperand(0, TmpV); MadeChange = true; }
1390 TmpV = SimplifyDemandedVectorElts(I->getOperand(1), DemandedElts,
1391 UndefElts2, Depth + 1);
1392 if (TmpV) { I->setOperand(1, TmpV); MadeChange = true; }
1393
1394 // Output elements are undefined if both are undefined. Consider things
1395 // like undef&0. The result is known zero, not undef.
1396 UndefElts &= UndefElts2;
1397 break;
13981380 case Instruction::FPTrunc:
13991381 case Instruction::FPExt:
14001382 TmpV = SimplifyDemandedVectorElts(I->getOperand(0), DemandedElts, UndefElts,
16461628 break;
16471629 }
16481630 }
1631
1632 // TODO: We bail completely on integer div/rem and shifts because they have
1633 // UB/poison potential, but that should be refined.
1634 BinaryOperator *BO;
1635 if (match(I, m_BinOp(BO)) && !BO->isIntDivRem() && !BO->isShift()) {
1636 TmpV = SimplifyDemandedVectorElts(I->getOperand(0), DemandedElts, UndefElts,
1637 Depth + 1);
1638 if (TmpV) { I->setOperand(0, TmpV); MadeChange = true; }
1639 TmpV = SimplifyDemandedVectorElts(I->getOperand(1), DemandedElts,
1640 UndefElts2, Depth + 1);
1641 if (TmpV) { I->setOperand(1, TmpV); MadeChange = true; }
1642
1643 // TODO: If this is a potentially poison-producing instruction, we need
1644 // to drop the wrapping/exact flags?
1645
1646 // Output elements are undefined if both are undefined. Consider things
1647 // like undef&0. The result is known zero, not undef.
1648 UndefElts &= UndefElts2;
1649 }
1650
16491651 return MadeChange ? I : nullptr;
16501652 }
17081708
17091709 define <4 x float> @test_mask3_vfnmsub_ss(<4 x float> %a, <4 x float> %b, <4 x float> %c, i8 %mask) {
17101710 ; CHECK-LABEL: @test_mask3_vfnmsub_ss(
1711 ; CHECK-NEXT: [[DOTRHS:%.*]] = extractelement <4 x float> [[A:%.*]], i32 0
1711 ; CHECK-NEXT: [[DOTRHS:%.*]] = extractelement <4 x float> [[A:%.*]], i64 0
17121712 ; CHECK-NEXT: [[TMP1:%.*]] = fsub float -0.000000e+00, [[DOTRHS]]
17131713 ; CHECK-NEXT: [[TMP2:%.*]] = extractelement <4 x float> [[B:%.*]], i32 0
17141714 ; CHECK-NEXT: [[DOTRHS1:%.*]] = extractelement <4 x float> [[C:%.*]], i64 0
347347
348348 define <4 x double> @fsub(<4 x double> %v) {
349349 ; CHECK-LABEL: @fsub(
350 ; CHECK-NEXT: [[B:%.*]] = fsub <4 x double> 4.100000e+01, double 4.200000e+01, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]]
350 ; CHECK-NEXT: [[B:%.*]] = fsub <4 x double> undef, double undef, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]]
351351 ; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x double> [[V]], <4 x double> [[B]], <4 x i32>
352352 ; CHECK-NEXT: ret <4 x double> [[S]]
353353 ;
370370
371371 define <4 x double> @fdiv_constant_op0(<4 x double> %v) {
372372 ; CHECK-LABEL: @fdiv_constant_op0(
373 ; CHECK-NEXT: [[B:%.*]] = fdiv fast <4 x double> 4.100000e+01, double 4.200000e+01, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]]
373 ; CHECK-NEXT: [[B:%.*]] = fdiv fast <4 x double> undef, double undef, double 4.300000e+01, double 4.400000e+01>, [[V:%.*]]
374374 ; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x double> [[V]], <4 x double> [[B]], <4 x i32>
375375 ; CHECK-NEXT: ret <4 x double> [[S]]
376376 ;
391391
392392 define <4 x double> @frem(<4 x double> %v) {
393393 ; CHECK-LABEL: @frem(
394 ; CHECK-NEXT: [[B:%.*]] = frem <4 x double> 4.300000e+01, double 4.400000e+01>, [[V:%.*]]
394 ; CHECK-NEXT: [[B:%.*]] = frem <4 x double> undef, double undef>, [[V:%.*]]
395395 ; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x double> [[B]], <4 x double> [[V]], <4 x i32>
396396 ; CHECK-NEXT: ret <4 x double> [[S]]
397397 ;
790790
791791 define <4 x double> @frem_frem(<4 x double> %v0) {
792792 ; CHECK-LABEL: @frem_frem(
793 ; CHECK-NEXT: [[T1:%.*]] = frem <4 x double> , [[V0:%.*]]
794 ; CHECK-NEXT: [[T2:%.*]] = frem <4 x double> [[V0]],
793 ; CHECK-NEXT: [[T1:%.*]] = frem <4 x double> , [[V0:%.*]]
794 ; CHECK-NEXT: [[T2:%.*]] = frem <4 x double> [[V0]],
795795 ; CHECK-NEXT: [[T3:%.*]] = shufflevector <4 x double> [[T1]], <4 x double> [[T2]], <4 x i32>
796796 ; CHECK-NEXT: ret <4 x double> [[T3]]
797797 ;
12831283
12841284 define <4 x double> @fdiv_2_vars(<4 x double> %v0, <4 x double> %v1) {
12851285 ; CHECK-LABEL: @fdiv_2_vars(
1286 ; CHECK-NEXT: [[T1:%.*]] = fdiv <4 x double> , [[V0:%.*]]
1287 ; CHECK-NEXT: [[T2:%.*]] = fdiv <4 x double> [[V1:%.*]],
1286 ; CHECK-NEXT: [[T1:%.*]] = fdiv <4 x double> , [[V0:%.*]]
1287 ; CHECK-NEXT: [[T2:%.*]] = fdiv <4 x double> [[V1:%.*]],
12881288 ; CHECK-NEXT: [[T3:%.*]] = shufflevector <4 x double> [[T1]], <4 x double> [[T2]], <4 x i32>
12891289 ; CHECK-NEXT: ret <4 x double> [[T3]]
12901290 ;
420420
421421 define <3 x float> @shuf_fadd(<3 x float> %x) {
422422 ; CHECK-LABEL: @shuf_fadd(
423 ; CHECK-NEXT: [[BO:%.*]] = fadd <3 x float> [[X:%.*]], 3.000000e+00>
423 ; CHECK-NEXT: [[BO:%.*]] = fadd <3 x float> [[X:%.*]], undef>
424424 ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32>
425425 ; CHECK-NEXT: ret <3 x float> [[R]]
426426 ;
431431
432432 define <3 x float> @shuf_fsub(<3 x float> %x) {
433433 ; CHECK-LABEL: @shuf_fsub(
434 ; CHECK-NEXT: [[BO:%.*]] = fsub fast <3 x float> 2.000000e+00, float 3.000000e+00>, [[X:%.*]]
434 ; CHECK-NEXT: [[BO:%.*]] = fsub fast <3 x float> undef, float 3.000000e+00>, [[X:%.*]]
435435 ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32>
436436 ; CHECK-NEXT: ret <3 x float> [[R]]
437437 ;
442442
443443 define <3 x float> @shuf_fmul(<3 x float> %x) {
444444 ; CHECK-LABEL: @shuf_fmul(
445 ; CHECK-NEXT: [[BO:%.*]] = fmul reassoc <3 x float> [[X:%.*]], 3.000000e+00>
445 ; CHECK-NEXT: [[BO:%.*]] = fmul reassoc <3 x float> [[X:%.*]], undef>
446446 ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32>
447447 ; CHECK-NEXT: ret <3 x float> [[R]]
448448 ;
453453
454454 define <3 x float> @shuf_fdiv_const_op0(<3 x float> %x) {
455455 ; CHECK-LABEL: @shuf_fdiv_const_op0(
456 ; CHECK-NEXT: [[BO:%.*]] = fdiv reassoc ninf <3 x float> 2.000000e+00, float 3.000000e+00>, [[X:%.*]]
456 ; CHECK-NEXT: [[BO:%.*]] = fdiv reassoc ninf <3 x float> undef, float 3.000000e+00>, [[X:%.*]]
457457 ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32>
458458 ; CHECK-NEXT: ret <3 x float> [[R]]
459459 ;
464464
465465 define <3 x float> @shuf_fdiv_const_op1(<3 x float> %x) {
466466 ; CHECK-LABEL: @shuf_fdiv_const_op1(
467 ; CHECK-NEXT: [[BO:%.*]] = fdiv nnan ninf <3 x float> [[X:%.*]], 3.000000e+00>
467 ; CHECK-NEXT: [[BO:%.*]] = fdiv nnan ninf <3 x float> [[X:%.*]], undef>
468468 ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32>
469469 ; CHECK-NEXT: ret <3 x float> [[R]]
470470 ;
475475
476476 define <3 x float> @shuf_frem_const_op0(<3 x float> %x) {
477477 ; CHECK-LABEL: @shuf_frem_const_op0(
478 ; CHECK-NEXT: [[BO:%.*]] = frem nnan <3 x float> 2.000000e+00, float 3.000000e+00>, [[X:%.*]]
478 ; CHECK-NEXT: [[BO:%.*]] = frem nnan <3 x float> undef, float 3.000000e+00>, [[X:%.*]]
479479 ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32>
480480 ; CHECK-NEXT: ret <3 x float> [[R]]
481481 ;
486486
487487 define <3 x float> @shuf_frem_const_op1(<3 x float> %x) {
488488 ; CHECK-LABEL: @shuf_frem_const_op1(
489 ; CHECK-NEXT: [[BO:%.*]] = frem reassoc ninf <3 x float> [[X:%.*]], 1.000000e+00, float 2.000000e+00, float 3.000000e+00>
489 ; CHECK-NEXT: [[BO:%.*]] = frem reassoc ninf <3 x float> [[X:%.*]], undef, float 2.000000e+00, float 3.000000e+00>
490490 ; CHECK-NEXT: [[R:%.*]] = shufflevector <3 x float> [[BO]], <3 x float> undef, <3 x i32>
491491 ; CHECK-NEXT: ret <3 x float> [[R]]
492492 ;
951951
952952 define <2 x float> @fsub_splat_constant1(<2 x float> %x) {
953953 ; CHECK-LABEL: @fsub_splat_constant1(
954 ; CHECK-NEXT: [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], 0x7FF8000000000000>
954 ; CHECK-NEXT: [[TMP1:%.*]] = fadd <2 x float> [[X:%.*]], undef>
955955 ; CHECK-NEXT: [[R:%.*]] = shufflevector <2 x float> [[TMP1]], <2 x float> undef, <2 x i32> zeroinitializer
956956 ; CHECK-NEXT: ret <2 x float> [[R]]
957957 ;