llvm.org GIT mirror llvm / f157979
[CVP] Process binary operations even when def is local Summary: This patch adds processing of binary operations when the def of operands are in the same block (i.e. local processing). Earlier we bailed out in such cases (the bail out was introduced in rL252032) because LVI at that time was more precise about context at the end of basic blocks, which implied local def and use analysis didn't benefit CVP. Since then we've added support for LVI in presence of assumes and guards. The test cases added show how local def processing in CVP helps adding more information to the ashr, sdiv, srem and add operators. Note: processCmp which suffers from the same problem will be handled in a later patch. Reviewers: philip, apilipenko, SjoerdMeijer, hfinkel Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D38766 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315634 91177308-0d34-0410-b5e6-96231b3b80d8 Anna Thomas 2 years ago
5 changed file(s) with 136 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
334334 return true;
335335 }
336336
337 // Helper function to rewrite srem and sdiv. As a policy choice, we choose not
338 // to waste compile time on anything where the operands are local defs. While
339 // LVI can sometimes reason about such cases, it's not its primary purpose.
340 static bool hasLocalDefs(BinaryOperator *SDI) {
341 for (Value *O : SDI->operands()) {
342 auto *I = dyn_cast(O);
343 if (I && I->getParent() == SDI->getParent())
344 return true;
345 }
346 return false;
347 }
348
349337 static bool hasPositiveOperands(BinaryOperator *SDI, LazyValueInfo *LVI) {
350338 Constant *Zero = ConstantInt::get(SDI->getType(), 0);
351339 for (Value *O : SDI->operands()) {
357345 }
358346
359347 static bool processSRem(BinaryOperator *SDI, LazyValueInfo *LVI) {
360 if (SDI->getType()->isVectorTy() || hasLocalDefs(SDI) ||
348 if (SDI->getType()->isVectorTy() ||
361349 !hasPositiveOperands(SDI, LVI))
362350 return false;
363351
375363 /// conditions, this can sometimes prove conditions instcombine can't by
376364 /// exploiting range information.
377365 static bool processSDiv(BinaryOperator *SDI, LazyValueInfo *LVI) {
378 if (SDI->getType()->isVectorTy() || hasLocalDefs(SDI) ||
366 if (SDI->getType()->isVectorTy() ||
379367 !hasPositiveOperands(SDI, LVI))
380368 return false;
381369
390378 }
391379
392380 static bool processAShr(BinaryOperator *SDI, LazyValueInfo *LVI) {
393 if (SDI->getType()->isVectorTy() || hasLocalDefs(SDI))
381 if (SDI->getType()->isVectorTy())
394382 return false;
395383
396384 Constant *Zero = ConstantInt::get(SDI->getType(), 0);
414402 if (DontProcessAdds)
415403 return false;
416404
417 if (AddOp->getType()->isVectorTy() || hasLocalDefs(AddOp))
405 if (AddOp->getType()->isVectorTy())
418406 return false;
419407
420408 bool NSW = AddOp->hasNoSignedWrap();
306306 ret void
307307 }
308308
309 ; single basic block loop
310 ; because the loop exit condition is SLT, we can supplement the iv add
311 ; (iv.next def) with an nsw.
312 ; CHECK-LABEL: @test16(
313 define i32 @test16(i32* %n, i32* %a) {
314 preheader:
315 br label %loop
316
317 loop:
318 ; CHECK: %iv.next = add nsw i32 %iv, 1
319 %iv = phi i32 [ 0, %preheader ], [ %iv.next, %loop ]
320 %acc = phi i32 [ 0, %preheader ], [ %acc.curr, %loop ]
321 %x = load atomic i32, i32* %a unordered, align 8
322 fence acquire
323 %acc.curr = add i32 %acc, %x
324 %iv.next = add i32 %iv, 1
325 %nval = load atomic i32, i32* %n unordered, align 8
326 %cmp = icmp slt i32 %iv.next, %nval
327 br i1 %cmp, label %loop, label %exit
328
329 exit:
330 ret i32 %acc.curr
331 }
5353 exit:
5454 ret void
5555 }
56
57 ; looping case where loop has exactly one block
58 ; at the point of ashr, we know that the operand is always greater than 0,
59 ; because of the guard before it, so we can transform it to lshr.
60 declare void @llvm.experimental.guard(i1,...)
61 ; CHECK-LABEL: @test4
62 define void @test4(i32 %n) {
63 entry:
64 %cmp = icmp sgt i32 %n, 0
65 br i1 %cmp, label %loop, label %exit
66
67 loop:
68 ; CHECK: lshr i32 %a, 1
69 %a = phi i32 [ %n, %entry ], [ %shr, %loop ]
70 %cond = icmp sgt i32 %a, 2
71 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
72 %shr = ashr i32 %a, 1
73 br i1 %cond, label %loop, label %exit
74
75 exit:
76 ret void
77 }
78
79 ; same test as above with assume instead of guard.
80 declare void @llvm.assume(i1)
81 ; CHECK-LABEL: @test5
82 define void @test5(i32 %n) {
83 entry:
84 %cmp = icmp sgt i32 %n, 0
85 br i1 %cmp, label %loop, label %exit
86
87 loop:
88 ; CHECK: lshr i32 %a, 1
89 %a = phi i32 [ %n, %entry ], [ %shr, %loop ]
90 %cond = icmp sgt i32 %a, 4
91 call void @llvm.assume(i1 %cond)
92 %shr = ashr i32 %a, 1
93 %loopcond = icmp sgt i32 %shr, 8
94 br i1 %loopcond, label %loop, label %exit
95
96 exit:
97 ret void
98 }
5151 exit:
5252 ret void
5353 }
54
55 ; looping case where loop has exactly one block
56 ; at the point of sdiv, we know that %a is always greater than 0,
57 ; because of the guard before it, so we can transform it to udiv.
58 declare void @llvm.experimental.guard(i1,...)
59 ; CHECK-LABEL: @test4
60 define void @test4(i32 %n) {
61 entry:
62 %cmp = icmp sgt i32 %n, 0
63 br i1 %cmp, label %loop, label %exit
64
65 loop:
66 ; CHECK: udiv i32 %a, 6
67 %a = phi i32 [ %n, %entry ], [ %div, %loop ]
68 %cond = icmp sgt i32 %a, 4
69 call void(i1,...) @llvm.experimental.guard(i1 %cond) [ "deopt"() ]
70 %div = sdiv i32 %a, 6
71 br i1 %cond, label %loop, label %exit
72
73 exit:
74 ret void
75 }
76
77 ; same test as above with assume instead of guard.
78 declare void @llvm.assume(i1)
79 ; CHECK-LABEL: @test5
80 define void @test5(i32 %n) {
81 entry:
82 %cmp = icmp sgt i32 %n, 0
83 br i1 %cmp, label %loop, label %exit
84
85 loop:
86 ; CHECK: udiv i32 %a, 6
87 %a = phi i32 [ %n, %entry ], [ %div, %loop ]
88 %cond = icmp sgt i32 %a, 4
89 call void @llvm.assume(i1 %cond)
90 %div = sdiv i32 %a, 6
91 %loopcond = icmp sgt i32 %div, 8
92 br i1 %loopcond, label %loop, label %exit
93
94 exit:
95 ret void
96 }
1818 if.end:
1919 ret void
2020 }
21
22 ; looping case where loop has exactly one block
23 ; at the point of srem, we know that %a is always greater than 0,
24 ; because of the assume before it, so we can transform it to urem.
25 declare void @llvm.assume(i1)
26 ; CHECK-LABEL: @test4
27 define void @test4(i32 %n) {
28 entry:
29 %cmp = icmp sgt i32 %n, 0
30 br i1 %cmp, label %loop, label %exit
31
32 loop:
33 ; CHECK: urem i32 %a, 6
34 %a = phi i32 [ %n, %entry ], [ %rem, %loop ]
35 %cond = icmp sgt i32 %a, 4
36 call void @llvm.assume(i1 %cond)
37 %rem = srem i32 %a, 6
38 %loopcond = icmp sgt i32 %rem, 8
39 br i1 %loopcond, label %loop, label %exit
40
41 exit:
42 ret void
43 }