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