Files
clang-p2996/llvm/test/Analysis/BasicAA/cs-cs.ll
Nikita Popov 57d57b1afd [AAEval] Make compatible with opaque pointers
With opaque pointers, we cannot use the pointer element type to
determine the LocationSize for the AA query. Instead, -aa-eval
tests are now required to have an explicit load or store for any
pointer they want to compute alias results for, and the load/store
types are used to determine the location size.

This may affect ordering of results, and sorting within one result,
as the type is not considered part of the sorted string anymore.

To somewhat minimize the churn, printing still uses faux typed
pointer notation.
2022-03-16 10:02:11 +01:00

456 lines
29 KiB
LLVM

; RUN: opt < %s -aa-pipeline=basic-aa -passes=aa-eval -print-all-alias-modref-info -S 2>&1 | FileCheck %s
target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:32:64-v128:32:128-a0:0:32-n32"
target triple = "arm-apple-ios"
declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1) #0
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i1) #0
declare void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32) #0
declare void @a_readonly_func(i8*) #1
declare void @a_writeonly_func(i8*) #2
define void @test2(i8* %P, i8* %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test2:
; CHECK: MayAlias: i8* %P, i8* %Q
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
}
define void @test2_atomic(i8* %P, i8* %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
ret void
; CHECK-LABEL: Function: test2_atomic:
; CHECK: MayAlias: i8* %P, i8* %Q
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
; CHECK: Both ModRef: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1) <-> tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
; CHECK: Both ModRef: tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1) <-> tail call void @llvm.memcpy.element.unordered.atomic.p0i8.p0i8.i64(i8* align 1 %P, i8* align 1 %Q, i64 12, i32 1)
}
define void @test2a(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test2a:
; CHECK: NoAlias: i8* %P, i8* %Q
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
}
define void @test2b(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
%R = getelementptr i8, i8* %P, i64 12
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test2b:
; CHECK: NoAlias: i8* %P, i8* %Q
; CHECK: NoAlias: i8* %P, i8* %R
; CHECK: NoAlias: i8* %Q, i8* %R
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
}
define void @test2c(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
%R = getelementptr i8, i8* %P, i64 11
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test2c:
; CHECK: NoAlias: i8* %P, i8* %Q
; CHECK: NoAlias: i8* %P, i8* %R
; CHECK: NoAlias: i8* %Q, i8* %R
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
}
define void @test2d(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
%R = getelementptr i8, i8* %P, i64 -12
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test2d:
; CHECK: NoAlias: i8* %P, i8* %Q
; CHECK: NoAlias: i8* %P, i8* %R
; CHECK: NoAlias: i8* %Q, i8* %R
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
}
define void @test2e(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
%R = getelementptr i8, i8* %P, i64 -11
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test2e:
; CHECK: NoAlias: i8* %P, i8* %Q
; CHECK: NoAlias: i8* %P, i8* %R
; CHECK: NoAlias: i8* %Q, i8* %R
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %R, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
}
define void @test3(i8* %P, i8* %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test3:
; CHECK: MayAlias: i8* %P, i8* %Q
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
}
define void @test3a(i8* noalias %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test3a:
; CHECK: NoAlias: i8* %P, i8* %Q
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 8, i1 false)
}
define void @test4(i8* %P, i8* noalias %Q) #3 {
load i8, i8* %P
load i8, i8* %Q
tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test4:
; CHECK: NoAlias: i8* %P, i8* %Q
; CHECK: Just Mod (MustAlias): Ptr: i8* %P <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memset.p0i8.i64(i8* %P, i8 42, i64 8, i1 false)
}
define void @test5(i8* %P, i8* %Q, i8* %R) #3 {
load i8, i8* %P
load i8, i8* %Q
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test5:
; CHECK: MayAlias: i8* %P, i8* %Q
; CHECK: MayAlias: i8* %P, i8* %R
; CHECK: MayAlias: i8* %Q, i8* %R
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
; CHECK: Both ModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
; CHECK: Both ModRef: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
}
define void @test5a(i8* noalias %P, i8* noalias %Q, i8* noalias %R) nounwind ssp {
load i8, i8* %P
load i8, i8* %Q
load i8, i8* %R
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
ret void
; CHECK-LABEL: Function: test5a:
; CHECK: NoAlias: i8* %P, i8* %Q
; CHECK: NoAlias: i8* %P, i8* %R
; CHECK: NoAlias: i8* %Q, i8* %R
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: NoModRef: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
; CHECK: Just Mod: Ptr: i8* %P <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
; CHECK: NoModRef: Ptr: i8* %Q <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
; CHECK: Just Ref: Ptr: i8* %R <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false)
; CHECK: Just Mod: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %R, i64 12, i1 false) <-> tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %P, i8* %Q, i64 12, i1 false)
}
define void @test6(i8* %P) #3 {
load i8, i8* %P
call void @llvm.memset.p0i8.i64(i8* align 8 %P, i8 -51, i64 32, i1 false)
call void @a_readonly_func(i8* %P)
ret void
; CHECK-LABEL: Function: test6:
; CHECK: Just Mod (MustAlias): Ptr: i8* %P <-> call void @llvm.memset.p0i8.i64(i8* align 8 %P, i8 -51, i64 32, i1 false)
; CHECK: Just Ref: Ptr: i8* %P <-> call void @a_readonly_func(i8* %P)
; CHECK: Just Mod: call void @llvm.memset.p0i8.i64(i8* align 8 %P, i8 -51, i64 32, i1 false) <-> call void @a_readonly_func(i8* %P)
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @llvm.memset.p0i8.i64(i8* align 8 %P, i8 -51, i64 32, i1 false)
}
define void @test7(i8* %P) #3 {
load i8, i8* %P
call void @a_writeonly_func(i8* %P)
call void @a_readonly_func(i8* %P)
ret void
; CHECK-LABEL: Function: test7:
; CHECK: Just Mod: Ptr: i8* %P <-> call void @a_writeonly_func(i8* %P)
; CHECK: Just Ref: Ptr: i8* %P <-> call void @a_readonly_func(i8* %P)
; CHECK: Just Mod: call void @a_writeonly_func(i8* %P) <-> call void @a_readonly_func(i8* %P)
; CHECK: Just Ref: call void @a_readonly_func(i8* %P) <-> call void @a_writeonly_func(i8* %P)
}
declare void @an_inaccessiblememonly_func() #4
declare void @an_inaccessibleorargmemonly_func(i8*) #5
declare void @an_argmemonly_func(i8*) #0
define void @test8(i8* %p) {
entry:
%q = getelementptr i8, i8* %p, i64 16
load i8, i8* %p
load i8, i8* %q
call void @a_readonly_func(i8* %p)
call void @an_inaccessiblememonly_func()
call void @a_writeonly_func(i8* %q)
call void @an_inaccessiblememonly_func()
call void @an_inaccessibleorargmemonly_func(i8* %q)
call void @an_argmemonly_func(i8* %q)
ret void
; CHECK-LABEL: Function: test8
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func()
; CHECK: NoModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func()
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) <-> call void @an_inaccessiblememonly_func()
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @a_readonly_func(i8* %p)
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @a_writeonly_func(i8* %q)
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @an_inaccessiblememonly_func()
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
; CHECK: NoModRef: call void @an_inaccessiblememonly_func() <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Just Mod: call void @a_writeonly_func(i8* %q) <-> call void @an_inaccessiblememonly_func()
; CHECK: Just Mod: call void @a_writeonly_func(i8* %q) <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
; CHECK: Just Mod: call void @a_writeonly_func(i8* %q) <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) <-> call void @a_readonly_func(i8* %p)
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) <-> call void @a_writeonly_func(i8* %q)
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) <-> call void @an_inaccessiblememonly_func()
; CHECK: Both ModRef (MustAlias): call void @an_inaccessibleorargmemonly_func(i8* %q) <-> call void @an_argmemonly_func(i8* %q)
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) <-> call void @a_readonly_func(i8* %p)
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) <-> call void @a_writeonly_func(i8* %q)
; CHECK: NoModRef: call void @an_argmemonly_func(i8* %q) <-> call void @an_inaccessiblememonly_func()
; CHECK: Both ModRef (MustAlias): call void @an_argmemonly_func(i8* %q) <-> call void @an_inaccessibleorargmemonly_func(i8* %q)
}
;; test that MustAlias is set for calls when no MayAlias is found.
declare void @another_argmemonly_func(i8*, i8*) #0
define void @test8a(i8* noalias %p, i8* noalias %q) {
entry:
load i8, i8* %p
load i8, i8* %q
call void @another_argmemonly_func(i8* %p, i8* %q)
ret void
; CHECK-LABEL: Function: test8a
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @another_argmemonly_func(i8* %p, i8* %q)
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @another_argmemonly_func(i8* %p, i8* %q)
}
define void @test8b(i8* %p, i8* %q) {
entry:
load i8, i8* %p
load i8, i8* %q
call void @another_argmemonly_func(i8* %p, i8* %q)
ret void
; CHECK-LABEL: Function: test8b
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @another_argmemonly_func(i8* %p, i8* %q)
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @another_argmemonly_func(i8* %p, i8* %q)
}
;; test that unknown operand bundle has unknown effect to the heap
define void @test9(i8* %p) {
; CHECK-LABEL: Function: test9
entry:
%q = getelementptr i8, i8* %p, i64 16
load i8, i8* %p
load i8, i8* %q
call void @a_readonly_func(i8* %p) [ "unknown"() ]
call void @an_inaccessiblememonly_func() [ "unknown"() ]
call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
ret void
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: call void @a_readonly_func(i8* %p) [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
; CHECK: Both ModRef: call void @a_readonly_func(i8* %p) [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: call void @a_readonly_func(i8* %p) [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) [ "unknown"() ]
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) [ "unknown"() ]
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() [ "unknown"() ]
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) [ "unknown"() ]
}
;; test callsite overwrite of unknown operand bundle
define void @test10(i8* %p) {
; CHECK-LABEL: Function: test10
entry:
%q = getelementptr i8, i8* %p, i64 16
load i8, i8* %p
load i8, i8* %q
call void @a_readonly_func(i8* %p) #6 [ "unknown"() ]
call void @an_inaccessiblememonly_func() #7 [ "unknown"() ]
call void @an_inaccessibleorargmemonly_func(i8* %q) #8 [ "unknown"() ]
call void @an_argmemonly_func(i8* %q) #9 [ "unknown"() ]
ret void
; CHECK: Just Ref: Ptr: i8* %p <-> call void @a_readonly_func(i8* %p) #9 [ "unknown"() ]
; CHECK: Just Ref: Ptr: i8* %q <-> call void @a_readonly_func(i8* %p) #9 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %p <-> call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
; CHECK: NoModRef: Ptr: i8* %q <-> call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Both ModRef: Ptr: i8* %p <-> call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): Ptr: i8* %q <-> call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #9 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #9 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: Just Ref: call void @a_readonly_func(i8* %p) #9 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() #10 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #9 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessiblememonly_func() #10 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]
; CHECK: NoModRef: call void @an_inaccessiblememonly_func() #10 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #9 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ] <-> call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ]
; CHECK: Both ModRef: call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ] <-> call void @a_readonly_func(i8* %p) #9 [ "unknown"() ]
; CHECK: NoModRef: call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ] <-> call void @an_inaccessiblememonly_func() #10 [ "unknown"() ]
; CHECK: Both ModRef (MustAlias): call void @an_argmemonly_func(i8* %q) #12 [ "unknown"() ] <-> call void @an_inaccessibleorargmemonly_func(i8* %q) #11 [ "unknown"() ]
}
; CHECK: attributes #0 = { argmemonly nofree nounwind willreturn writeonly }
; CHECK-NEXT: attributes #1 = { argmemonly nofree nounwind willreturn }
; CHECK-NEXT: attributes #2 = { argmemonly nosync nounwind willreturn }
; CHECK-NEXT: attributes #3 = { noinline nounwind readonly }
; CHECK-NEXT: attributes #4 = { noinline nounwind writeonly }
; CHECK-NEXT: attributes #5 = { nounwind ssp }
; CHECK-NEXT: attributes #6 = { inaccessiblememonly nounwind }
; CHECK-NEXT: attributes #7 = { inaccessiblemem_or_argmemonly nounwind }
; CHECK-NEXT: attributes #8 = { argmemonly nounwind }
; CHECK-NEXT: attributes #9 = { readonly }
; CHECK-NEXT: attributes #10 = { inaccessiblememonly }
; CHECK-NEXT: attributes #11 = { inaccessiblemem_or_argmemonly }
; CHECK-NEXT: attributes #12 = { argmemonly }
attributes #0 = { argmemonly nounwind }
attributes #1 = { noinline nounwind readonly }
attributes #2 = { noinline nounwind writeonly }
attributes #3 = { nounwind ssp }
attributes #4 = { inaccessiblememonly nounwind }
attributes #5 = { inaccessiblemem_or_argmemonly nounwind }
attributes #6 = { readonly }
attributes #7 = { inaccessiblememonly }
attributes #8 = { inaccessiblemem_or_argmemonly }
attributes #9 = { argmemonly }