xref: /llvm-project/llvm/test/Transforms/LowerConstantIntrinsics/builtin-object-size-range.ll (revision e4db3f0d97681a10a76e71465f1379801cd45f54)
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2; RUN: opt -passes=lower-constant-intrinsics -S < %s | FileCheck %s
3
4target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-unknown-linux-gnu"
6
7declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg)
8declare noalias ptr @malloc(i64 noundef) #0
9
10define i64 @select_alloc_size(i1 %cond) {
11; CHECK-LABEL: @select_alloc_size(
12; CHECK-NEXT:    [[SIZE:%.*]] = select i1 [[COND:%.*]], i64 3, i64 4
13; CHECK-NEXT:    [[PTR:%.*]] = alloca i8, i64 [[SIZE]], align 1
14; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i64 4, i64 3
15; CHECK-NEXT:    ret i64 [[RES]]
16;
17  %size = select i1 %cond, i64 3, i64 4
18  %ptr = alloca i8, i64 %size
19  %objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false)
20  %objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 true, i1 true, i1 false)
21  %res = select i1 %cond, i64 %objsize_max, i64 %objsize_min
22  ret i64 %res
23}
24
25define i64 @select_malloc_size(i1 %cond) {
26; CHECK-LABEL: @select_malloc_size(
27; CHECK-NEXT:    [[SIZE:%.*]] = select i1 [[COND:%.*]], i64 3, i64 4
28; CHECK-NEXT:    [[PTR:%.*]] = call noalias ptr @malloc(i64 noundef [[SIZE]])
29; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i64 4, i64 3
30; CHECK-NEXT:    ret i64 [[RES]]
31;
32  %size = select i1 %cond, i64 3, i64 4
33  %ptr = call noalias ptr @malloc(i64 noundef %size)
34  %objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false)
35  %objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 true, i1 true, i1 false)
36  %res = select i1 %cond, i64 %objsize_max, i64 %objsize_min
37  ret i64 %res
38}
39
40define i64 @select_gep_offset(i1 %cond) {
41; CHECK-LABEL: @select_gep_offset(
42; CHECK-NEXT:    [[PTR:%.*]] = alloca i8, i64 10, align 1
43; CHECK-NEXT:    [[OFFSET:%.*]] = select i1 [[COND:%.*]], i64 3, i64 4
44; CHECK-NEXT:    [[PTR_SLIDE:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[OFFSET]]
45; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i64 7, i64 6
46; CHECK-NEXT:    ret i64 [[RES]]
47;
48  %ptr = alloca i8, i64 10
49  %offset = select i1 %cond, i64 3, i64 4
50  %ptr.slide = getelementptr inbounds i8, ptr %ptr, i64 %offset
51  %objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
52  %objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
53  %res = select i1 %cond, i64 %objsize_max, i64 %objsize_min
54  ret i64 %res
55}
56
57define i64 @select_gep_neg_offset(i1 %c0, i1 %c1) {
58; CHECK-LABEL: @select_gep_neg_offset(
59; CHECK-NEXT:    [[PTR:%.*]] = alloca i8, i64 10, align 1
60; CHECK-NEXT:    [[PTR_SLIDE_1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 5
61; CHECK-NEXT:    [[OFFSET:%.*]] = select i1 [[COND:%.*]], i64 -3, i64 -4
62; CHECK-NEXT:    [[PTR_SLIDE_2:%.*]] = getelementptr inbounds i8, ptr [[PTR_SLIDE_1]], i64 [[OFFSET]]
63; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C1:%.*]], i64 9, i64 8
64; CHECK-NEXT:    ret i64 [[RES]]
65;
66  %ptr = alloca i8, i64 10
67  %ptr.slide.1 = getelementptr inbounds i8, ptr %ptr, i64 5
68  %offset = select i1 %c0, i64 -3, i64 -4
69  %ptr.slide.2 = getelementptr inbounds i8, ptr %ptr.slide.1, i64 %offset
70  %objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide.2, i1 false, i1 true, i1 false)
71  %objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide.2, i1 true, i1 true, i1 false)
72  %res = select i1 %c1, i64 %objsize_max, i64 %objsize_min
73  ret i64 %res
74}
75
76define i64 @select_neg_oob_offset(i1 %c0, i1 %c1) {
77; CHECK-LABEL: @select_neg_oob_offset(
78; CHECK-NEXT:    [[PTR:%.*]] = alloca i8, i64 10, align 1
79; CHECK-NEXT:    [[OFFSET:%.*]] = select i1 [[C0:%.*]], i64 -3, i64 -4
80; CHECK-NEXT:    [[PTR_SLIDE:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[OFFSET]]
81; CHECK-NEXT:    [[RES:%.*]] = select i1 [[C1:%.*]], i64 -1, i64 0
82; CHECK-NEXT:    ret i64 [[RES]]
83;
84  %ptr = alloca i8, i64 10
85  %offset = select i1 %c0, i64 -3, i64 -4
86  %ptr.slide = getelementptr inbounds i8, ptr %ptr, i64 %offset
87  %objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
88  %objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
89  %res = select i1 %c1, i64 %objsize_max, i64 %objsize_min
90  ret i64 %res
91}
92
93define i64 @select_gep_offsets(i1 %cond) {
94; CHECK-LABEL: @select_gep_offsets(
95; CHECK-NEXT:    [[PTR:%.*]] = alloca [10 x i8], i64 2, align 1
96; CHECK-NEXT:    [[OFFSET:%.*]] = select i1 [[COND:%.*]], i32 0, i32 1
97; CHECK-NEXT:    [[PTR_SLIDE:%.*]] = getelementptr inbounds [10 x i8], ptr [[PTR]], i32 [[OFFSET]], i32 5
98; CHECK-NEXT:    [[RES:%.*]] = select i1 [[COND]], i64 15, i64 5
99; CHECK-NEXT:    ret i64 [[RES]]
100;
101  %ptr = alloca [10 x i8], i64 2
102  %offset = select i1 %cond, i32 0, i32 1
103  %ptr.slide = getelementptr inbounds [10 x i8], ptr %ptr, i32 %offset, i32 5
104  %objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
105  %objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
106  %res = select i1 %cond, i64 %objsize_max, i64 %objsize_min
107  ret i64 %res
108}
109
110define i64 @select_gep_oob_overapproximated_offsets(i1 %cond) {
111; CHECK-LABEL: @select_gep_oob_overapproximated_offsets(
112; CHECK-NEXT:    [[BASE1:%.*]] = alloca [288 x i8], align 16
113; CHECK-NEXT:    [[SELECT0:%.*]] = select i1 [[COND:%.*]], i64 -4, i64 -64
114; CHECK-NEXT:    [[SELECT1:%.*]] = select i1 [[COND]], i64 16, i64 64
115; CHECK-NEXT:    [[GEP0:%.*]] = getelementptr inbounds nuw i8, ptr [[BASE1]], i64 [[SELECT1]]
116; CHECK-NEXT:    [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[GEP0]], i64 [[SELECT0]]
117; CHECK-NEXT:    ret i64 -1
118;
119  %base1 = alloca [288 x i8], align 16
120  %select0 = select i1 %cond, i64 -4, i64 -64
121  %select1 = select i1 %cond, i64 16, i64 64
122; This never actually goes oob, but because we approximate each select
123; independently, this actually ranges in [16 - 64 ; 64 - 4] instead of [64 - 64; 16 - 4]
124  %gep0 = getelementptr inbounds nuw i8, ptr %base1, i64 %select1
125  %gep1 = getelementptr inbounds i8, ptr %gep0, i64 %select0
126  %call = call i64 @llvm.objectsize.i64.p0(ptr %gep1, i1 false, i1 true, i1 false)
127  ret i64 %call
128}
129
130
131attributes #0 = { nounwind allocsize(0) }
132