Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit d78238e

Browse files
committed
Add a todo and tests to Address a review commnt from D50925 [NFC]
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@340978 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent a9f18e9 commit d78238e

File tree

2 files changed

+120
-1
lines changed

2 files changed

+120
-1
lines changed

lib/Transforms/Scalar/LICM.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,9 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
737737

738738
// We can only hoist a store that we can prove writes a value which is not
739739
// read or overwritten within the loop. For those cases, we fallback to
740-
// load store promotion instead.
740+
// load store promotion instead. TODO: We can extend this to cases where
741+
// there is exactly one write to the location and that write dominates an
742+
// arbitrary number of reads in the loop.
741743
auto &AS = CurAST->getAliasSetFor(MemoryLocation::get(SI));
742744

743745
if (AS.isRef() || !AS.isMustAlias())

test/Transforms/LICM/store-hoisting.ll

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,3 +309,120 @@ loop:
309309
exit:
310310
ret void
311311
}
312+
313+
; TODO: could validly hoist the store here since we know what value
314+
; the load must observe.
315+
define i32 @test_dominated_read(i32* %loc) {
316+
; CHECK-LABEL: @test_dominated_read
317+
; CHECK-LABEL: exit:
318+
; CHECK: store i32 0, i32* %loc
319+
entry:
320+
br label %loop
321+
322+
loop:
323+
%iv = phi i32 [0, %entry], [%iv.next, %loop]
324+
store i32 0, i32* %loc
325+
%reload = load i32, i32* %loc
326+
%iv.next = add i32 %iv, 1
327+
%cmp = icmp slt i32 %iv, 200
328+
br i1 %cmp, label %loop, label %exit
329+
330+
exit:
331+
ret i32 %reload
332+
}
333+
334+
; TODO: could validly hoist the store since we already hoisted the load and
335+
; it's no longer in the loop.
336+
define i32 @test_dominating_read(i32* %loc) {
337+
; CHECK-LABEL: @test_dominating_read
338+
; CHECK-LABEL: exit:
339+
; CHECK: store i32 0, i32* %loc
340+
entry:
341+
br label %loop
342+
343+
loop:
344+
%iv = phi i32 [0, %entry], [%iv.next, %loop]
345+
%reload = load i32, i32* %loc
346+
store i32 0, i32* %loc
347+
%iv.next = add i32 %iv, 1
348+
%cmp = icmp slt i32 %iv, 200
349+
br i1 %cmp, label %loop, label %exit
350+
351+
exit:
352+
ret i32 %reload
353+
}
354+
355+
declare void @readonly() readonly
356+
357+
; TODO: can legally hoist since value read by call is known
358+
define void @test_dominated_readonly(i32* %loc) {
359+
; CHECK-LABEL: @test_dominated_readonly
360+
; CHECK-LABEL: loop:
361+
; CHECK: store i32 0, i32* %loc
362+
; CHECK-LABEL: exit:
363+
entry:
364+
br label %loop
365+
366+
loop:
367+
%iv = phi i32 [0, %entry], [%iv.next, %loop]
368+
store i32 0, i32* %loc
369+
call void @readonly()
370+
%iv.next = add i32 %iv, 1
371+
%cmp = icmp slt i32 %iv, 200
372+
br i1 %cmp, label %loop, label %exit
373+
374+
exit:
375+
ret void
376+
}
377+
378+
; While technically possible to hoist the store to %loc, this runs across
379+
; a funemental limitation of alias sets since both stores and the call are
380+
; within the same alias set and we can't distinguish them cheaply.
381+
define void @test_aliasset_fn(i32* %loc, i32* %loc2) {
382+
; CHECK-LABEL: @test_aliasset_fn
383+
; CHECK-LABEL: loop:
384+
; CHECK: store i32 0, i32* %loc
385+
; CHECK-LABEL: exit:
386+
entry:
387+
br label %loop
388+
389+
loop:
390+
%iv = phi i32 [0, %entry], [%iv.next, %loop]
391+
store i32 0, i32* %loc
392+
call void @readonly()
393+
store i32 %iv, i32* %loc2
394+
%iv.next = add i32 %iv, 1
395+
%cmp = icmp slt i32 %iv, 200
396+
br i1 %cmp, label %loop, label %exit
397+
398+
exit:
399+
ret void
400+
}
401+
402+
403+
; If we can't tell if the value is read before the write, we can't hoist the
404+
; write over the potential read (since we don't know the value read)
405+
define void @neg_may_read(i32* %loc, i1 %maybe) {
406+
; CHECK-LABEL: @neg_may_read
407+
; CHECK-LABEL: loop:
408+
; CHECK: store i32 0, i32* %loc
409+
; CHECK-LABEL: exit:
410+
entry:
411+
br label %loop
412+
413+
loop:
414+
%iv = phi i32 [0, %entry], [%iv.next, %merge]
415+
;; maybe is a placeholder for an unanalyzable condition
416+
br i1 %maybe, label %taken, label %merge
417+
taken:
418+
call void @readonly()
419+
br label %merge
420+
merge:
421+
store i32 0, i32* %loc
422+
%iv.next = add i32 %iv, 1
423+
%cmp = icmp slt i32 %iv, 200
424+
br i1 %cmp, label %loop, label %exit
425+
426+
exit:
427+
ret void
428+
}

0 commit comments

Comments
 (0)