mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2026-04-21 23:17:16 +00:00
[SLSR] handle candidate form (B + i * S)
Summary: With this patch, SLSR may rewrite S1: X = B + i * S S2: Y = B + i' * S to S2: Y = X + (i' - i) * S A secondary improvement: if (i' - i) is a power of 2, emit Y as X + (S << log(i' - i)). (S << log(i' -i)) is in a canonical form and thus more likely GVN'ed than (i' - i) * S. Test Plan: slsr-add.ll Reviewers: hfinkel, sanjoy, meheff, broune, eliben Reviewed By: eliben Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D8983 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@235019 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -5,8 +5,8 @@ target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Do not perform SLSR on &input[s] and &input[s * 2] which fit into addressing
|
||||
; modes of X86.
|
||||
define i32 @slsr_gep(i32* %input, i64 %s) {
|
||||
; CHECK-LABEL: @slsr_gep(
|
||||
define i32 @no_slsr_gep(i32* %input, i64 %s) {
|
||||
; CHECK-LABEL: @no_slsr_gep(
|
||||
; v0 = input[0];
|
||||
%p0 = getelementptr inbounds i32, i32* %input, i64 0
|
||||
%v0 = load i32, i32* %p0
|
||||
@@ -28,3 +28,17 @@ define i32 @slsr_gep(i32* %input, i64 %s) {
|
||||
ret i32 %2
|
||||
}
|
||||
|
||||
define void @no_slsr_add(i32 %b, i32 %s) {
|
||||
; CHECK-LABEL: @no_slsr_add(
|
||||
%1 = add i32 %b, %s
|
||||
; CHECK: add i32 %b, %s
|
||||
call void @foo(i32 %1)
|
||||
%s2 = mul i32 %s, 2
|
||||
; CHECK: %s2 = mul i32 %s, 2
|
||||
%2 = add i32 %b, %s2
|
||||
; CHECK: add i32 %b, %s2
|
||||
call void @foo(i32 %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @foo(i32 %a)
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
; RUN: opt < %s -slsr -gvn -dce -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-i64:64-v16:16-v32:32-n16:32:64"
|
||||
|
||||
define void @shl(i32 %b, i32 %s) {
|
||||
; CHECK-LABEL: @shl(
|
||||
%1 = add i32 %b, %s
|
||||
; [[BASIS:%[a-zA-Z0-9]+]] = add i32 %b, %s
|
||||
call void @foo(i32 %1)
|
||||
%s2 = shl i32 %s, 1
|
||||
%2 = add i32 %b, %s2
|
||||
; add i32 [[BASIS]], %s
|
||||
call void @foo(i32 %2)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @stride_is_2s(i32 %b, i32 %s) {
|
||||
; CHECK-LABEL: @stride_is_2s(
|
||||
%s2 = shl i32 %s, 1
|
||||
; CHECK: %s2 = shl i32 %s, 1
|
||||
%1 = add i32 %b, %s2
|
||||
; CHECK: [[t1:%[a-zA-Z0-9]+]] = add i32 %b, %s2
|
||||
call void @foo(i32 %1)
|
||||
%s4 = shl i32 %s, 2
|
||||
%2 = add i32 %b, %s4
|
||||
; CHECK: [[t2:%[a-zA-Z0-9]+]] = add i32 [[t1]], %s2
|
||||
call void @foo(i32 %2)
|
||||
%s6 = mul i32 %s, 6
|
||||
%3 = add i32 %b, %s6
|
||||
; CHECK: add i32 [[t2]], %s2
|
||||
call void @foo(i32 %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
define void @stride_is_3s(i32 %b, i32 %s) {
|
||||
; CHECK-LABEL: @stride_is_3s(
|
||||
%1 = add i32 %s, %b
|
||||
; CHECK: [[t1:%[a-zA-Z0-9]+]] = add i32 %s, %b
|
||||
call void @foo(i32 %1)
|
||||
%s4 = shl i32 %s, 2
|
||||
%2 = add i32 %s4, %b
|
||||
; CHECK: [[bump:%[a-zA-Z0-9]+]] = mul i32 %s, 3
|
||||
; CHECK: [[t2:%[a-zA-Z0-9]+]] = add i32 [[t1]], [[bump]]
|
||||
call void @foo(i32 %2)
|
||||
%s7 = mul i32 %s, 7
|
||||
%3 = add i32 %s7, %b
|
||||
; CHECK: add i32 [[t2]], [[bump]]
|
||||
call void @foo(i32 %3)
|
||||
ret void
|
||||
}
|
||||
|
||||
; foo(b + 6 * s);
|
||||
; foo(b + 4 * s);
|
||||
; foo(b + 2 * s);
|
||||
; =>
|
||||
; t1 = b + 6 * s;
|
||||
; foo(t1);
|
||||
; s2 = 2 * s;
|
||||
; t2 = t1 - s2;
|
||||
; foo(t2);
|
||||
; t3 = t2 - s2;
|
||||
; foo(t3);
|
||||
define void @stride_is_minus_2s(i32 %b, i32 %s) {
|
||||
; CHECK-LABEL: @stride_is_minus_2s(
|
||||
%s6 = mul i32 %s, 6
|
||||
%1 = add i32 %b, %s6
|
||||
; CHECK: [[t1:%[a-zA-Z0-9]+]] = add i32 %b, %s6
|
||||
; CHECK: call void @foo(i32 [[t1]])
|
||||
call void @foo(i32 %1)
|
||||
%s4 = shl i32 %s, 2
|
||||
%2 = add i32 %b, %s4
|
||||
; CHECK: [[bump:%[a-zA-Z0-9]+]] = shl i32 %s, 1
|
||||
; CHECK: [[t2:%[a-zA-Z0-9]+]] = sub i32 [[t1]], [[bump]]
|
||||
call void @foo(i32 %2)
|
||||
; CHECK: call void @foo(i32 [[t2]])
|
||||
%s2 = shl i32 %s, 1
|
||||
%3 = add i32 %b, %s2
|
||||
; CHECK: [[t3:%[a-zA-Z0-9]+]] = sub i32 [[t2]], [[bump]]
|
||||
call void @foo(i32 %3)
|
||||
; CHECK: call void @foo(i32 [[t3]])
|
||||
ret void
|
||||
}
|
||||
|
||||
; t = b + (s << 3);
|
||||
; foo(t);
|
||||
; foo(b + s);
|
||||
;
|
||||
; do not rewrite b + s to t - 7 * s because the latter is more complicated.
|
||||
define void @simple_enough(i32 %b, i32 %s) {
|
||||
; CHECK-LABEL: @simple_enough(
|
||||
%s8 = shl i32 %s, 3
|
||||
%1 = add i32 %b, %s8
|
||||
call void @foo(i32 %1)
|
||||
%2 = add i32 %b, %s
|
||||
; CHECK: [[t:%[a-zA-Z0-9]+]] = add i32 %b, %s{{$}}
|
||||
call void @foo(i32 %2)
|
||||
; CHECK: call void @foo(i32 [[t]])
|
||||
ret void
|
||||
}
|
||||
|
||||
declare void @foo(i32 %a)
|
||||
@@ -79,7 +79,7 @@ define i32 @slsr3(i32 %b, i32 %s) {
|
||||
|
||||
%b1 = add i32 %b, 2
|
||||
%mul1 = mul i32 %b1, %s
|
||||
; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = mul i32 %s, 2
|
||||
; CHECK: [[BUMP:%[a-zA-Z0-9]+]] = shl i32 %s, 1
|
||||
; CHECK: %mul1 = add i32 %mul0, [[BUMP]]
|
||||
%v1 = call i32 @foo(i32 %mul1)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user