[llvm] r185776 - Eliminate trivial redundant loads across nocapture+readonly calls to uncaptured

Nick Lewycky nicholas at mxc.ca
Sun Jul 7 11:58:13 PDT 2013


Duncan Sands wrote:
> Hi Nick,
>
> On 07/07/13 12:15, Nick Lewycky wrote:
>> Author: nicholas
>> Date: Sun Jul 7 05:15:16 2013
>> New Revision: 185776
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=185776&view=rev
>> Log:
>> Eliminate trivial redundant loads across nocapture+readonly calls to
>> uncaptured
>> pointer arguments.
>
> ...
>
>> --- llvm/trunk/test/Transforms/GVN/readattrs.ll (added)
>> +++ llvm/trunk/test/Transforms/GVN/readattrs.ll Sun Jul 7 05:15:16 2013
>> @@ -0,0 +1,17 @@
>> +; RUN: opt -gvn -S -o - < %s | FileCheck %s
>> +
>> +target datalayout =
>> "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
>>
>> +target triple = "x86_64-unknown-linux-gnu"
>> +
>> +declare void @use(i8* readonly nocapture)
>> +
>> +define i8 @test() {
>> + %a = alloca i8
>> + store i8 1, i8* %a
>> + call void @use(i8* %a)
>> + %b = load i8* %a
>> + ret i8 %b
>> +; CHECK: define i8 @test
>> +; CHECK: call void @use(i8* %a)
>> +; CHECK-NEXT: ret i8 1
>> +}
>
> Why is nocapture relevant here? It would be correct to eliminate the second
> load in this example even if @use captured it.

That's correct, it can be improved. However, consider this example:

declare void @use2(i8* readonly)
declare void @somefunction()

define i8 @test2() {
   %a = alloca i8
   store i8 1, i8* %a
   call void @use2(i8* %a)
   call void @somefunction()
   %b = load i8* %a
   ret i8 %b
}

where the load can't be folded away. If you add a nocapture to @use2 and 
it can. That's why nocapture is relevant.

I think that scanning uses is cheap enough, but that scanning all 
instructions looking for a call-after-capture is expensive. We may be 
able to do it.

Nick



More information about the llvm-commits mailing list