1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 20:51:52 +01:00
Tyker c86946593e Reland [AssumeBundles] Use operand bundles to encode alignment assumptions
NOTE: There is a mailing list discussion on this: http://lists.llvm.org/pipermail/llvm-dev/2019-December/137632.html

Complemantary to the assumption outliner prototype in D71692, this patch
shows how we could simplify the code emitted for an alignemnt
assumption. The generated code is smaller, less fragile, and it makes it
easier to recognize the additional use as a "assumption use".

As mentioned in D71692 and on the mailing list, we could adopt this
scheme, and similar schemes for other patterns, without adopting the
assumption outlining.
2020-09-12 15:36:06 +02:00

109 lines
5.1 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature
; RUN: opt -inline -preserve-alignment-assumptions-during-inlining -S < %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-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
define void @hello(float* align 128 nocapture %a, float* nocapture readonly %c) #0 {
; CHECK-LABEL: define {{[^@]+}}@hello
; CHECK-SAME: (float* nocapture align 128 [[A:%.*]], float* nocapture readonly [[C:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX]], align 4
; CHECK-NEXT: ret void
;
entry:
%0 = load float, float* %c, align 4
%arrayidx = getelementptr inbounds float, float* %a, i64 5
store float %0, float* %arrayidx, align 4
ret void
}
define void @foo(float* nocapture %a, float* nocapture readonly %c) #0 {
; CHECK-LABEL: define {{[^@]+}}@foo
; CHECK-SAME: (float* nocapture [[A:%.*]], float* nocapture readonly [[C:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(float* [[A]], i64 128) ]
; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; CHECK-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4
; CHECK-NEXT: ret void
;
entry:
tail call void @hello(float* %a, float* %c)
%0 = load float, float* %c, align 4
%arrayidx = getelementptr inbounds float, float* %a, i64 7
store float %0, float* %arrayidx, align 4
ret void
}
define void @fooa(float* nocapture align 128 %a, float* nocapture readonly %c) #0 {
; CHECK-LABEL: define {{[^@]+}}@fooa
; CHECK-SAME: (float* nocapture align 128 [[A:%.*]], float* nocapture readonly [[C:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; CHECK-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4
; CHECK-NEXT: ret void
;
entry:
tail call void @hello(float* %a, float* %c)
%0 = load float, float* %c, align 4
%arrayidx = getelementptr inbounds float, float* %a, i64 7
store float %0, float* %arrayidx, align 4
ret void
}
define void @hello2(float* align 128 nocapture %a, float* align 128 nocapture %b, float* nocapture readonly %c) #0 {
; CHECK-LABEL: define {{[^@]+}}@hello2
; CHECK-SAME: (float* nocapture align 128 [[A:%.*]], float* nocapture align 128 [[B:%.*]], float* nocapture readonly [[C:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX]], align 4
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX1]], align 4
; CHECK-NEXT: ret void
;
entry:
%0 = load float, float* %c, align 4
%arrayidx = getelementptr inbounds float, float* %a, i64 5
store float %0, float* %arrayidx, align 4
%arrayidx1 = getelementptr inbounds float, float* %b, i64 8
store float %0, float* %arrayidx1, align 4
ret void
}
define void @foo2(float* nocapture %a, float* nocapture %b, float* nocapture readonly %c) #0 {
; CHECK-LABEL: define {{[^@]+}}@foo2
; CHECK-SAME: (float* nocapture [[A:%.*]], float* nocapture [[B:%.*]], float* nocapture readonly [[C:%.*]]) #0
; CHECK-NEXT: entry:
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(float* [[A]], i64 128) ]
; CHECK-NEXT: call void @llvm.assume(i1 true) [ "align"(float* [[B]], i64 128) ]
; CHECK-NEXT: [[TMP0:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX_I:%.*]] = getelementptr inbounds float, float* [[A]], i64 5
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX_I]], align 4
; CHECK-NEXT: [[ARRAYIDX1_I:%.*]] = getelementptr inbounds float, float* [[B]], i64 8
; CHECK-NEXT: store float [[TMP0]], float* [[ARRAYIDX1_I]], align 4
; CHECK-NEXT: [[TMP1:%.*]] = load float, float* [[C]], align 4
; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, float* [[A]], i64 7
; CHECK-NEXT: store float [[TMP1]], float* [[ARRAYIDX]], align 4
; CHECK-NEXT: ret void
;
entry:
tail call void @hello2(float* %a, float* %b, float* %c)
%0 = load float, float* %c, align 4
%arrayidx = getelementptr inbounds float, float* %a, i64 7
store float %0, float* %arrayidx, align 4
ret void
}
attributes #0 = { nounwind uwtable }