1 ; RUN: opt -S --passes=ipsccp,deadargelim --force-specialization < %s | FileCheck %s --check-prefix=NO-GLOBALS
2 ; RUN: opt -S --passes=ipsccp,deadargelim --force-specialization --funcspec-on-address < %s | FileCheck %s --check-prefix=GLOBALS
3 @G = global [10 x i32] zeroinitializer, align 4
5 define internal i32 @f(ptr %p) noinline {
7 %0 = load i32, ptr %p, align 4
8 store i32 0, ptr %p, align 4
12 define internal i32 @g(i32 %x, i32 %y, ptr %p) noinline {
14 %cmp = icmp sgt i32 %x, %y
15 br i1 %cmp, label %if.then, label %if.else
24 %x.addr.0 = phi i32 [ %x, %if.then ], [ 11, %if.else ]
25 %p.addr.0 = phi ptr [ @G, %if.then ], [ %p, %if.else ]
26 %call = call i32 @f(ptr %p.addr.0)
27 %add = add nsw i32 %call, %x.addr.0
31 define i32 @h0(ptr %p) {
33 %call = call i32 @g(i32 2, i32 1, ptr %p)
39 %call = call i32 @f(ptr @G)
45 %call = call i32 @f(ptr getelementptr inbounds (i32, ptr @G, i64 1))
49 ; Check if specialisation on the address of a non-const global variable
50 ; is not allowed, then it is not performed.
52 ; NO-GLOBALS-LABEL: define internal i32 @g()
53 ; NO-GLOBALS: call i32 @f(ptr @G)
55 ; NO-GLOBALS-LABEL: define i32 @h0(ptr %p)
56 ; NO-GLOBALS:call i32 @g()
58 ; NO-GLOBALS-LABEL: define i32 @h1()
59 ; NO-GLOBALS: call i32 @f(ptr @G)
61 ; NO-GLOBALS-LABEL: define i32 @h2()
62 ; NO-GLOBALS: call i32 @f(ptr getelementptr inbounds (i32, ptr @G, i64 1))
64 ; Check if specialisation on the address of a non-const global variable
65 ; is allowed, then it is performed where possible.
67 ; GLOBALS-LABEL: define internal i32 @g()
68 ; GLOBALS: call i32 @f.specialized.2()
70 ; GLOBALS-LABEL: define i32 @h0(ptr %p)
71 ; GLOBALS: call i32 @g()
73 ; GLOBALS-LABEL: define i32 @h1()
74 ; GLOBALS: call i32 @f.specialized.2()
76 ; GLOBALS-LABEL: define i32 @h2()
77 ; GLOBALS: call i32 @f.specialized.1()