mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
966bb89b1a
Making a width of GEP Index, which is used for address calculation, to be one of the pointer properties in the Data Layout. p[address space]:size:memory_size:alignment:pref_alignment:index_size_in_bits. The index size parameter is optional, if not specified, it is equal to the pointer size. Till now, the InstCombiner normalized GEPs and extended the Index operand to the pointer width. It works fine if you can convert pointer to integer for address calculation and all registered targets do this. But some ISAs have very restricted instruction set for the pointer calculation. During discussions were desided to retrieve information for GEP index from the Data Layout. http://lists.llvm.org/pipermail/llvm-dev/2018-January/120416.html I added an interface to the Data Layout and I changed the InstCombiner and some other passes to take the Index width into account. This change does not affect any in-tree target. I added tests to cover data layouts with explicitly specified index size. Differential Revision: https://reviews.llvm.org/D42123 llvm-svn: 325102
68 lines
2.3 KiB
LLVM
68 lines
2.3 KiB
LLVM
; RUN: opt -O3 -S -analyze -scalar-evolution < %s | FileCheck %s
|
|
|
|
target datalayout = "e-m:m-p:40:64:64:32-i32:32-i16:16-i8:8-n32"
|
|
|
|
;
|
|
; This file contains phase ordering tests for scalar evolution.
|
|
; Test that the standard passes don't obfuscate the IR so scalar evolution can't
|
|
; recognize expressions.
|
|
|
|
; CHECK: test1
|
|
; The loop body contains two increments by %div.
|
|
; Make sure that 2*%div is recognizable, and not expressed as a bit mask of %d.
|
|
; CHECK: --> {%p,+,(8 * (%d /u 4))}
|
|
define void @test1(i32 %d, i32* %p) nounwind uwtable ssp {
|
|
entry:
|
|
%div = udiv i32 %d, 4
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.inc, %entry
|
|
%p.addr.0 = phi i32* [ %p, %entry ], [ %add.ptr1, %for.inc ]
|
|
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%cmp = icmp ne i32 %i.0, 64
|
|
br i1 %cmp, label %for.body, label %for.end
|
|
|
|
for.body: ; preds = %for.cond
|
|
store i32 0, i32* %p.addr.0, align 4
|
|
%add.ptr = getelementptr inbounds i32, i32* %p.addr.0, i32 %div
|
|
store i32 1, i32* %add.ptr, align 4
|
|
%add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %div
|
|
br label %for.inc
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add i32 %i.0, 1
|
|
br label %for.cond
|
|
|
|
for.end: ; preds = %for.cond
|
|
ret void
|
|
}
|
|
|
|
; CHECK: test1a
|
|
; Same thing as test1, but it is even more tempting to fold 2 * (%d /u 2)
|
|
; CHECK: --> {%p,+,(8 * (%d /u 2))}
|
|
define void @test1a(i32 %d, i32* %p) nounwind uwtable ssp {
|
|
entry:
|
|
%div = udiv i32 %d, 2
|
|
br label %for.cond
|
|
|
|
for.cond: ; preds = %for.inc, %entry
|
|
%p.addr.0 = phi i32* [ %p, %entry ], [ %add.ptr1, %for.inc ]
|
|
%i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
|
|
%cmp = icmp ne i32 %i.0, 64
|
|
br i1 %cmp, label %for.body, label %for.end
|
|
|
|
for.body: ; preds = %for.cond
|
|
store i32 0, i32* %p.addr.0, align 4
|
|
%add.ptr = getelementptr inbounds i32, i32* %p.addr.0, i32 %div
|
|
store i32 1, i32* %add.ptr, align 4
|
|
%add.ptr1 = getelementptr inbounds i32, i32* %add.ptr, i32 %div
|
|
br label %for.inc
|
|
|
|
for.inc: ; preds = %for.body
|
|
%inc = add i32 %i.0, 1
|
|
br label %for.cond
|
|
|
|
for.end: ; preds = %for.cond
|
|
ret void
|
|
}
|