llvm.org GIT mirror llvm / bd99a1f
Back out "Re-land: Teach CorrelatedValuePropagation to reduce the width of udiv/urem instructions." This reverts r326908, originally landed as D44102. Reverted for causing performance regressions on x86. (These regressions are not yet understood.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327252 91177308-0d34-0410-b5e6-96231b3b80d8 Justin Lebar 2 years ago
3 changed file(s) with 0 addition(s) and 250 deletion(s). Raw diff Collapse all Expand all
5757 STATISTIC(NumReturns, "Number of return values propagated");
5858 STATISTIC(NumDeadCases, "Number of switch cases removed");
5959 STATISTIC(NumSDivs, "Number of sdiv converted to udiv");
60 STATISTIC(NumUDivs, "Number of udivs whose width was decreased");
6160 STATISTIC(NumAShrs, "Number of ashr converted to lshr");
6261 STATISTIC(NumSRems, "Number of srem converted to urem");
6362 STATISTIC(NumOverflows, "Number of overflow checks removed");
432431 return true;
433432 }
434433
435 /// Try to shrink a udiv/urem's width down to the smallest power of two that's
436 /// sufficient to contain its operands.
437 static bool processUDivOrURem(BinaryOperator *Instr, LazyValueInfo *LVI) {
438 assert(Instr->getOpcode() == Instruction::UDiv ||
439 Instr->getOpcode() == Instruction::URem);
440 if (Instr->getType()->isVectorTy())
441 return false;
442
443 // Find the smallest power of two bitwidth that's sufficient to hold Instr's
444 // operands.
445 auto OrigWidth = Instr->getType()->getIntegerBitWidth();
446 ConstantRange OperandRange(OrigWidth, /*isFullset=*/false);
447 for (Value *Operand : Instr->operands()) {
448 OperandRange = OperandRange.unionWith(
449 LVI->getConstantRange(Operand, Instr->getParent()));
450 }
451 // Don't shrink below 8 bits wide.
452 unsigned NewWidth = std::max(
453 PowerOf2Ceil(OperandRange.getUnsignedMax().getActiveBits()), 8);
454 // NewWidth might be greater than OrigWidth if OrigWidth is not a power of
455 // two.
456 if (NewWidth >= OrigWidth)
457 return false;
458
459 ++NumUDivs;
460 auto *TruncTy = Type::getIntNTy(Instr->getContext(), NewWidth);
461 auto *LHS = CastInst::Create(Instruction::Trunc, Instr->getOperand(0), TruncTy,
462 Instr->getName() + ".lhs.trunc", Instr);
463 auto *RHS = CastInst::Create(Instruction::Trunc, Instr->getOperand(1), TruncTy,
464 Instr->getName() + ".rhs.trunc", Instr);
465 auto *BO =
466 BinaryOperator::Create(Instr->getOpcode(), LHS, RHS, Instr->getName(), Instr);
467 auto *Zext = CastInst::Create(Instruction::ZExt, BO, Instr->getType(),
468 Instr->getName() + ".zext", Instr);
469 if (BO->getOpcode() == Instruction::UDiv)
470 BO->setIsExact(Instr->isExact());
471
472 Instr->replaceAllUsesWith(Zext);
473 Instr->eraseFromParent();
474 return true;
475 }
476
477434 static bool processSRem(BinaryOperator *SDI, LazyValueInfo *LVI) {
478435 if (SDI->getType()->isVectorTy() || !hasPositiveOperands(SDI, LVI))
479436 return false;
483440 SDI->getName(), SDI);
484441 SDI->replaceAllUsesWith(BO);
485442 SDI->eraseFromParent();
486
487 // Try to process our new urem.
488 processUDivOrURem(BO, LVI);
489
490443 return true;
491444 }
492445
505458 BO->setIsExact(SDI->isExact());
506459 SDI->replaceAllUsesWith(BO);
507460 SDI->eraseFromParent();
508
509 // Try to simplify our new udiv.
510 processUDivOrURem(BO, LVI);
511461
512462 return true;
513463 }
643593 break;
644594 case Instruction::SDiv:
645595 BBChanged |= processSDiv(cast(II), LVI);
646 break;
647 case Instruction::UDiv:
648 case Instruction::URem:
649 BBChanged |= processUDivOrURem(cast(II), LVI);
650596 break;
651597 case Instruction::AShr:
652598 BBChanged |= processAShr(cast(II), LVI);
+0
-95
test/Transforms/CorrelatedValuePropagation/udiv.ll less more
None ; RUN: opt < %s -correlated-propagation -S | FileCheck %s
1
2 ; CHECK-LABEL: @test_nop
3 define void @test_nop(i32 %n) {
4 ; CHECK udiv i32 %n, 100
5 %div = udiv i32 %n, 100
6 ret void
7 }
8
9 ; CHECK-LABEL: @test1(
10 define void @test1(i32 %n) {
11 entry:
12 %cmp = icmp ule i32 %n, 65535
13 br i1 %cmp, label %bb, label %exit
14
15 bb:
16 ; CHECK: udiv i16
17 %div = udiv i32 %n, 100
18 br label %exit
19
20 exit:
21 ret void
22 }
23
24 ; CHECK-LABEL: @test2(
25 define void @test2(i32 %n) {
26 entry:
27 %cmp = icmp ule i32 %n, 65536
28 br i1 %cmp, label %bb, label %exit
29
30 bb:
31 ; CHECK: udiv i32 %n, 100
32 %div = udiv i32 %n, 100
33 br label %exit
34
35 exit:
36 ret void
37 }
38
39 ; CHECK-LABEL: @test3(
40 define void @test3(i32 %m, i32 %n) {
41 entry:
42 %cmp1 = icmp ult i32 %m, 65535
43 %cmp2 = icmp ult i32 %n, 65535
44 %cmp = and i1 %cmp1, %cmp2
45 br i1 %cmp, label %bb, label %exit
46
47 bb:
48 ; CHECK: udiv i16
49 %div = udiv i32 %m, %n
50 br label %exit
51
52 exit:
53 ret void
54 }
55
56 ; CHECK-LABEL: @test4(
57 define void @test4(i32 %m, i32 %n) {
58 entry:
59 %cmp1 = icmp ult i32 %m, 65535
60 %cmp2 = icmp ule i32 %n, 65536
61 %cmp = and i1 %cmp1, %cmp2
62 br i1 %cmp, label %bb, label %exit
63
64 bb:
65 ; CHECK: udiv i32 %m, %n
66 %div = udiv i32 %m, %n
67 br label %exit
68
69 exit:
70 ret void
71 }
72
73 ; CHECK-LABEL: @test5
74 define void @test5(i32 %n) {
75 %trunc = and i32 %n, 65535
76 ; CHECK: udiv i16
77 %div = udiv i32 %trunc, 42
78 ret void
79 }
80
81 ; CHECK-LABEL: @test6
82 define void @test6(i32 %n) {
83 entry:
84 %cmp = icmp ule i32 %n, 255
85 br i1 %cmp, label %bb, label %exit
86
87 bb:
88 ; CHECK: udiv i8
89 %div = sdiv i32 %n, 100
90 br label %exit
91
92 exit:
93 ret void
94 }
+0
-101
test/Transforms/CorrelatedValuePropagation/urem.ll less more
None ; RUN: opt < %s -correlated-propagation -S | FileCheck %s
1
2 ; CHECK-LABEL: @test_nop
3 define void @test_nop(i32 %n) {
4 ; CHECK udiv i32 %n, 100
5 %div = udiv i32 %n, 100
6 ret void
7 }
8
9 ; CHECK-LABEL: @test1(
10 define void @test1(i32 %n) {
11 entry:
12 %cmp = icmp ule i32 %n, 65535
13 br i1 %cmp, label %bb, label %exit
14
15 bb:
16 ; CHECK: urem i16
17 %div = urem i32 %n, 100
18 br label %exit
19
20 exit:
21 ret void
22 }
23
24 ; CHECK-LABEL: @test2(
25 define void @test2(i32 %n) {
26 entry:
27 %cmp = icmp ule i32 %n, 65536
28 br i1 %cmp, label %bb, label %exit
29
30 bb:
31 ; CHECK: urem i32 %n, 100
32 %div = urem i32 %n, 100
33 br label %exit
34
35 exit:
36 ret void
37 }
38
39 ; CHECK-LABEL: @test3(
40 define void @test3(i32 %m, i32 %n) {
41 entry:
42 %cmp1 = icmp ult i32 %m, 65535
43 %cmp2 = icmp ult i32 %n, 65535
44 %cmp = and i1 %cmp1, %cmp2
45 br i1 %cmp, label %bb, label %exit
46
47 bb:
48 ; CHECK: urem i16
49 %div = urem i32 %m, %n
50 br label %exit
51
52 exit:
53 ret void
54 }
55
56 ; CHECK-LABEL: @test4(
57 define void @test4(i32 %m, i32 %n) {
58 entry:
59 %cmp1 = icmp ult i32 %m, 65535
60 %cmp2 = icmp ule i32 %n, 65536
61 %cmp = and i1 %cmp1, %cmp2
62 br i1 %cmp, label %bb, label %exit
63
64 bb:
65 ; CHECK: urem i32 %m, %n
66 %div = urem i32 %m, %n
67 br label %exit
68
69 exit:
70 ret void
71 }
72
73 ; CHECK-LABEL: @test5
74 define void @test5(i32 %n) {
75 %trunc = and i32 %n, 63
76 ; CHECK: urem i8
77 %div = urem i32 %trunc, 42
78 ret void
79 }
80
81 ; CHECK-LABEL: @test6
82 define void @test6(i32 %n) {
83 entry:
84 %cmp = icmp ule i32 %n, 255
85 br i1 %cmp, label %bb, label %exit
86
87 bb:
88 ; CHECK: urem i8
89 %div = srem i32 %n, 100
90 br label %exit
91
92 exit:
93 ret void
94 }
95
96 ; CHECK-LABEL: @non_power_of_2
97 define void @non_power_of_2(i24 %n) {
98 %div = urem i24 %n, 42
99 ret void
100 }