xref: /llvm-project/llvm/test/Transforms/SROA/non-integral-pointers.ll (revision 4f7e5d22060e8a89237ffb93c3e7be6e92fee8fe)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes='sroa<preserve-cfg>' -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-PRESERVE-CFG
3; RUN: opt -passes='sroa<modify-cfg>' -S < %s | FileCheck %s --check-prefixes=CHECK,CHECK-MODIFY-CFG
4
5; This test checks that SROA does not introduce ptrtoint and inttoptr
6; casts from and to non-integral pointers.  The "ni:4" bit in the
7; datalayout states that pointers of address space 4 are to be
8; considered "non-integral".
9
10target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128-ni:4"
11target triple = "x86_64-unknown-linux-gnu"
12
13define void @f0(i1 %alwaysFalse, i64 %val) {
14; CHECK-LABEL: @f0(
15; CHECK-NEXT:  entry:
16; CHECK-NEXT:    [[LOC:%.*]] = alloca i64, align 8
17; CHECK-NEXT:    store i64 [[VAL:%.*]], ptr [[LOC]], align 8
18; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
19; CHECK:       neverTaken:
20; CHECK-NEXT:    [[LOC_0_PTR:%.*]] = load ptr addrspace(4), ptr [[LOC]], align 8
21; CHECK-NEXT:    store i8 5, ptr addrspace(4) [[LOC_0_PTR]], align 1
22; CHECK-NEXT:    ret void
23; CHECK:       alwaysTaken:
24; CHECK-NEXT:    ret void
25;
26entry:
27  %loc = alloca i64
28  store i64 %val, ptr %loc
29  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
30
31neverTaken:
32  %ptr = load ptr addrspace(4), ptr %loc
33  store i8 5, ptr addrspace(4) %ptr
34  ret void
35
36alwaysTaken:
37  ret void
38}
39
40define i64 @f1(i1 %alwaysFalse, ptr addrspace(4) %val) {
41; CHECK-LABEL: @f1(
42; CHECK-NEXT:  entry:
43; CHECK-NEXT:    [[LOC:%.*]] = alloca ptr addrspace(4), align 8
44; CHECK-NEXT:    store ptr addrspace(4) [[VAL:%.*]], ptr [[LOC]], align 8
45; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
46; CHECK:       neverTaken:
47; CHECK-NEXT:    [[LOC_0_INT:%.*]] = load i64, ptr [[LOC]], align 8
48; CHECK-NEXT:    ret i64 [[LOC_0_INT]]
49; CHECK:       alwaysTaken:
50; CHECK-NEXT:    ret i64 42
51;
52entry:
53  %loc = alloca ptr addrspace(4)
54  store ptr addrspace(4) %val, ptr %loc
55  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
56
57neverTaken:
58  %int = load i64, ptr %loc
59  ret i64 %int
60
61alwaysTaken:
62  ret i64 42
63}
64
65define ptr addrspace(4) @memset(i1 %alwaysFalse) {
66; CHECK-LABEL: @memset(
67; CHECK-NEXT:  entry:
68; CHECK-NEXT:    [[X:%.*]] = alloca ptr addrspace(4), align 8
69; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 8 [[X]], i8 5, i64 8, i1 false)
70; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
71; CHECK:       neverTaken:
72; CHECK-NEXT:    [[X_0_X_FIELD_LD_0:%.*]] = load ptr addrspace(4), ptr [[X]], align 8
73; CHECK-NEXT:    ret ptr addrspace(4) [[X_0_X_FIELD_LD_0]]
74; CHECK:       alwaysTaken:
75; CHECK-NEXT:    ret ptr addrspace(4) null
76;
77entry:
78  %x = alloca ptr addrspace(4)
79  call void @llvm.memset.p0.i64(ptr align 8 %x, i8 5, i64 16, i1 false)
80  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
81
82neverTaken:
83  %x.field.ld.0 = load ptr addrspace(4), ptr %x
84  ret ptr addrspace(4) %x.field.ld.0
85
86alwaysTaken:
87  ret ptr addrspace(4) null
88}
89
90;; TODO: This one demonstrates a missed oppurtunity.  The only known bit
91;; pattern for a non-integral bit pattern is that null is zero.  As such
92;; we could do SROA and replace the memset w/a null store.  This will
93;; usually be gotten by instcombine.
94define ptr addrspace(4) @memset_null(i1 %alwaysFalse) {
95; CHECK-LABEL: @memset_null(
96; CHECK-NEXT:  entry:
97; CHECK-NEXT:    [[X:%.*]] = alloca ptr addrspace(4), align 8
98; CHECK-NEXT:    call void @llvm.memset.p0.i64(ptr align 8 [[X]], i8 0, i64 8, i1 false)
99; CHECK-NEXT:    br i1 [[ALWAYSFALSE:%.*]], label [[NEVERTAKEN:%.*]], label [[ALWAYSTAKEN:%.*]]
100; CHECK:       neverTaken:
101; CHECK-NEXT:    [[X_0_X_FIELD_LD_0:%.*]] = load ptr addrspace(4), ptr [[X]], align 8
102; CHECK-NEXT:    ret ptr addrspace(4) [[X_0_X_FIELD_LD_0]]
103; CHECK:       alwaysTaken:
104; CHECK-NEXT:    ret ptr addrspace(4) null
105;
106entry:
107  %x = alloca ptr addrspace(4)
108  call void @llvm.memset.p0.i64(ptr align 8 %x, i8 0, i64 16, i1 false)
109  br i1 %alwaysFalse, label %neverTaken, label %alwaysTaken
110
111neverTaken:
112  %x.field.ld.0 = load ptr addrspace(4), ptr %x
113  ret ptr addrspace(4) %x.field.ld.0
114
115alwaysTaken:
116  ret ptr addrspace(4) null
117}
118
119%union.anon = type { ptr }
120
121define ptr@f2(ptr addrspace(4) %p) {
122; CHECK-LABEL: @f2(
123; CHECK-NEXT:    [[DOTSROA_0:%.*]] = alloca ptr, align 8
124; CHECK-NEXT:    store ptr addrspace(4) [[P:%.*]], ptr [[DOTSROA_0]], align 8
125; CHECK-NEXT:    [[DOTSROA_0_0__SROA_0_0_:%.*]] = load ptr, ptr [[DOTSROA_0]], align 8
126; CHECK-NEXT:    ret ptr [[DOTSROA_0_0__SROA_0_0_]]
127;
128  %1 = alloca %union.anon, align 8
129  store ptr addrspace(4) %p, ptr %1, align 8
130  %2 = load ptr, ptr %1, align 8
131  ret ptr %2
132}
133
134declare void @llvm.memset.p0.i64(ptr, i8, i64, i1)
135;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
136; CHECK-MODIFY-CFG: {{.*}}
137; CHECK-PRESERVE-CFG: {{.*}}
138