422 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=lower-constant-intrinsics -S < %s | FileCheck %s3 4 5target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"6target triple = "x86_64-unknown-linux-gnu"7 8declare dso_local noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr allocsize(0)9declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg)10 11@buffer = dso_local global [4 x i8] zeroinitializer, align 112 13define dso_local i64 @pick_max(i32 noundef %n) local_unnamed_addr {14; CHECK-LABEL: @pick_max(15; CHECK-NEXT: entry:16; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 017; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]18; CHECK: if.else:19; CHECK-NEXT: [[MALLOCED:%.*]] = call noalias dereferenceable_or_null(8) ptr @malloc(i64 noundef 8)20; CHECK-NEXT: br label [[IF_END]]21; CHECK: if.end:22; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MALLOCED]], [[IF_ELSE]] ], [ @buffer, [[ENTRY:%.*]] ]23; CHECK-NEXT: ret i64 824;25entry:26 %cond = icmp eq i32 %n, 027 br i1 %cond, label %if.else, label %if.end28 29if.else:30 %malloced = call noalias dereferenceable_or_null(8) ptr @malloc(i64 noundef 8)31 br label %if.end32 33if.end:34 %p = phi ptr [ %malloced, %if.else ], [ @buffer, %entry ]35 %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 false, i1 true, i1 false)36 ret i64 %size37}38 39define dso_local i64 @pick_min(i32 noundef %n) local_unnamed_addr {40; CHECK-LABEL: @pick_min(41; CHECK-NEXT: entry:42; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 043; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]44; CHECK: if.else:45; CHECK-NEXT: [[MALLOCED:%.*]] = call noalias dereferenceable_or_null(8) ptr @malloc(i64 noundef 8)46; CHECK-NEXT: br label [[IF_END]]47; CHECK: if.end:48; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MALLOCED]], [[IF_ELSE]] ], [ @buffer, [[ENTRY:%.*]] ]49; CHECK-NEXT: ret i64 450;51entry:52 %cond = icmp eq i32 %n, 053 br i1 %cond, label %if.else, label %if.end54 55if.else:56 %malloced = call noalias dereferenceable_or_null(8) ptr @malloc(i64 noundef 8)57 br label %if.end58 59if.end:60 %p = phi ptr [ %malloced, %if.else ], [ @buffer, %entry ]61 %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 true, i1 true, i1 false)62 ret i64 %size63}64 65define i64 @pick_max_same(i32 %n) {66; CHECK-LABEL: @pick_max_same(67; CHECK-NEXT: entry:68; CHECK-NEXT: [[BUFFER:%.*]] = alloca i8, i64 20, align 169; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 070; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]71; CHECK: if.else:72; CHECK-NEXT: [[OFFSETED:%.*]] = getelementptr i8, ptr [[BUFFER]], i64 1073; CHECK-NEXT: br label [[IF_END]]74; CHECK: if.end:75; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED]], [[IF_ELSE]] ], [ [[BUFFER]], [[ENTRY:%.*]] ]76; CHECK-NEXT: ret i64 2077;78entry:79 %buffer = alloca i8, i64 2080 %cond = icmp eq i32 %n, 081 br i1 %cond, label %if.else, label %if.end82 83if.else:84 %offseted = getelementptr i8, ptr %buffer, i64 1085 br label %if.end86 87if.end:88 %p = phi ptr [ %offseted, %if.else ], [ %buffer, %entry ]89 %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 false, i1 true, i1 false)90 ret i64 %size91}92 93define i64 @pick_min_same(i32 %n) {94; CHECK-LABEL: @pick_min_same(95; CHECK-NEXT: entry:96; CHECK-NEXT: [[BUFFER:%.*]] = alloca i8, i64 20, align 197; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 098; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]99; CHECK: if.else:100; CHECK-NEXT: [[OFFSETED:%.*]] = getelementptr i8, ptr [[BUFFER]], i64 10101; CHECK-NEXT: br label [[IF_END]]102; CHECK: if.end:103; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED]], [[IF_ELSE]] ], [ [[BUFFER]], [[ENTRY:%.*]] ]104; CHECK-NEXT: ret i64 10105;106entry:107 %buffer = alloca i8, i64 20108 %cond = icmp eq i32 %n, 0109 br i1 %cond, label %if.else, label %if.end110 111if.else:112 %offseted = getelementptr i8, ptr %buffer, i64 10113 br label %if.end114 115if.end:116 %p = phi ptr [ %offseted, %if.else ], [ %buffer, %entry ]117 %size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 true, i1 true, i1 false)118 ret i64 %size119}120 121define dso_local i64 @pick_max_large(i1 %c) local_unnamed_addr {122; CHECK-LABEL: @pick_max_large(123; CHECK-NEXT: [[BUFFER:%.*]] = alloca i8, i64 -7, align 1124; CHECK-NEXT: [[S:%.*]] = select i1 [[C:%.*]], ptr null, ptr [[BUFFER]]125; CHECK-NEXT: ret i64 -1126;127 %buffer = alloca i8, i64 -7 ; Actually a very large positive integer128 %s = select i1 %c, ptr null, ptr %buffer129 %objsize = tail call i64 @llvm.objectsize.i64.p0(ptr %s, i1 false, i1 false, i1 false)130 ret i64 %objsize131 132}133 134define dso_local i64 @pick_max_one_oob(i1 %c0, i1 %c1) {135; CHECK-LABEL: @pick_max_one_oob(136; CHECK-NEXT: [[P:%.*]] = alloca [2 x i8], align 1137; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]138; CHECK: if.then:139; CHECK-NEXT: [[P_THEN:%.*]] = getelementptr inbounds [2 x i8], ptr [[P]], i64 0, i64 1140; CHECK-NEXT: br label [[IF_END:%.*]]141; CHECK: if.else:142; CHECK-NEXT: [[P_ELSE:%.*]] = getelementptr inbounds [2 x i8], ptr [[P]], i64 0, i64 -1143; CHECK-NEXT: br label [[IF_END]]144; CHECK: if.end:145; CHECK-NEXT: [[P_END:%.*]] = phi ptr [ [[P_ELSE]], [[IF_ELSE]] ], [ [[P_THEN]], [[IF_THEN]] ]146; CHECK-NEXT: [[OBJSIZE:%.*]] = select i1 [[C1:%.*]], i64 -1, i64 0147; CHECK-NEXT: ret i64 [[OBJSIZE]]148;149 %p = alloca [2 x i8], align 1150 br i1 %c0, label %if.then, label %if.else151 152if.then:153 %p.then = getelementptr inbounds [2 x i8], ptr %p, i64 0, i64 1154 br label %if.end155 156if.else:157 %p.else = getelementptr inbounds [2 x i8], ptr %p, i64 0, i64 -1158 br label %if.end159 160if.end:161 %p.end = phi ptr [%p.else, %if.else], [%p.then, %if.then]162 %objsize.max = call i64 @llvm.objectsize.i64.p0(ptr %p.end, i1 false, i1 true, i1 false)163 %objsize.min = call i64 @llvm.objectsize.i64.p0(ptr %p.end, i1 true, i1 true, i1 false)164 %objsize = select i1 %c1, i64 %objsize.max, i64 %objsize.min165 ret i64 %objsize166}167 168 169define i64 @pick_negative_offset(i32 %n) {170; CHECK-LABEL: @pick_negative_offset(171; CHECK-NEXT: entry:172; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1173; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20174; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0175; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]176; CHECK: if.else:177; CHECK-NEXT: [[BUFFER1:%.*]] = alloca i8, i64 20, align 1178; CHECK-NEXT: [[OFFSETED1:%.*]] = getelementptr i8, ptr [[BUFFER1]], i64 20179; CHECK-NEXT: br label [[IF_END]]180; CHECK: if.end:181; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED1]], [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY:%.*]] ]182; CHECK-NEXT: [[POFFSETED:%.*]] = getelementptr i8, ptr [[P]], i64 -4183; CHECK-NEXT: ret i64 4184;185entry:186 %buffer0 = alloca i8, i64 20187 %offseted0 = getelementptr i8, ptr %buffer0, i64 20188 %cond = icmp eq i32 %n, 0189 br i1 %cond, label %if.else, label %if.end190 191if.else:192 %buffer1 = alloca i8, i64 20193 %offseted1 = getelementptr i8, ptr %buffer1, i64 20194 br label %if.end195 196if.end:197 %p = phi ptr [ %offseted1, %if.else ], [ %offseted0, %entry ]198 %poffseted = getelementptr i8, ptr %p, i64 -4199 %size = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 false, i1 false, i1 false)200 ret i64 %size201}202 203define i64 @pick_negative_offset_different_width(i32 %n) {204; CHECK-LABEL: @pick_negative_offset_different_width(205; CHECK-NEXT: entry:206; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 4, align 1207; CHECK-NEXT: [[BUFFER1:%.*]] = alloca i8, i64 8, align 1208; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0209; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]210; CHECK: if.then:211; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 1212; CHECK-NEXT: br label [[IF_END1:%.*]]213; CHECK: if.else:214; CHECK-NEXT: [[OFFSETED1:%.*]] = getelementptr i8, ptr [[BUFFER1]], i64 6215; CHECK-NEXT: br label [[IF_END1]]216; CHECK: if.end:217; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED0]], [[IF_ELSE]] ], [ [[OFFSETED1]], [[IF_END]] ]218; CHECK-NEXT: [[POFFSETED:%.*]] = getelementptr i8, ptr [[P]], i64 -2219; CHECK-NEXT: ret i64 5220;221entry:222 %buffer0 = alloca i8, i64 4223 %buffer1 = alloca i8, i64 8224 %cond = icmp eq i32 %n, 0225 br i1 %cond, label %if.then, label %if.else226 227if.then:228 %offseted0 = getelementptr i8, ptr %buffer0, i64 1229 br label %if.end230 231if.else:232 %offseted1 = getelementptr i8, ptr %buffer1, i64 6233 br label %if.end234 235if.end:236 %p = phi ptr [ %offseted0, %if.then ], [ %offseted1, %if.else ]237 %poffseted = getelementptr i8, ptr %p, i64 -2238 %size = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 false, i1 false, i1 false)239 ret i64 %size240}241 242define i64 @pick_negative_offset_with_nullptr(i32 %n) {243; CHECK-LABEL: @pick_negative_offset_with_nullptr(244; CHECK-NEXT: entry:245; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1246; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20247; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0248; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]249; CHECK: if.else:250; CHECK-NEXT: br label [[IF_END]]251; CHECK: if.end:252; CHECK-NEXT: [[P0:%.*]] = phi ptr [ [[OFFSETED0]], [[ENTRY:%.*]] ], [ null, [[IF_ELSE]] ]253; CHECK-NEXT: [[P1:%.*]] = phi ptr [ null, [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY]] ]254; CHECK-NEXT: [[P0OFFSETED:%.*]] = getelementptr i8, ptr [[P0]], i64 -4255; CHECK-NEXT: [[P1OFFSETED:%.*]] = getelementptr i8, ptr [[P1]], i64 -4256; CHECK-NEXT: ret i64 4257;258entry:259 %buffer0 = alloca i8, i64 20260 %offseted0 = getelementptr i8, ptr %buffer0, i64 20261 %cond = icmp eq i32 %n, 0262 br i1 %cond, label %if.else, label %if.end263 264if.else:265 br label %if.end266 267if.end:268 %p0 = phi ptr [ %offseted0, %entry ], [ null, %if.else ]269 %p1 = phi ptr [ null, %if.else ], [ %offseted0, %entry ]270 %p0offseted = getelementptr i8, ptr %p0, i64 -4271 %p1offseted = getelementptr i8, ptr %p1, i64 -4272 %size0 = call i64 @llvm.objectsize.i64.p0(ptr %p0offseted, i1 false, i1 false, i1 false)273 %size1 = call i64 @llvm.objectsize.i64.p0(ptr %p1offseted, i1 false, i1 false, i1 false)274 %size = select i1 %cond, i64 %size0, i64 %size1275 ret i64 %size276}277 278define i64 @pick_negative_offset_with_unsized_nullptr(i32 %n) {279; CHECK-LABEL: @pick_negative_offset_with_unsized_nullptr(280; CHECK-NEXT: entry:281; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1282; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20283; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0284; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]285; CHECK: if.else:286; CHECK-NEXT: br label [[IF_END]]287; CHECK: if.end:288; CHECK-NEXT: [[P0:%.*]] = phi ptr [ [[OFFSETED0]], [[ENTRY:%.*]] ], [ null, [[IF_ELSE]] ]289; CHECK-NEXT: [[P1:%.*]] = phi ptr [ null, [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY]] ]290; CHECK-NEXT: [[P0OFFSETED:%.*]] = getelementptr i8, ptr [[P0]], i64 -4291; CHECK-NEXT: [[P1OFFSETED:%.*]] = getelementptr i8, ptr [[P1]], i64 -4292; CHECK-NEXT: ret i64 -1293;294entry:295 %buffer0 = alloca i8, i64 20296 %offseted0 = getelementptr i8, ptr %buffer0, i64 20297 %cond = icmp eq i32 %n, 0298 br i1 %cond, label %if.else, label %if.end299 300if.else:301 br label %if.end302 303if.end:304 %p0 = phi ptr [ %offseted0, %entry ], [ null, %if.else ]305 %p1 = phi ptr [ null, %if.else ], [ %offseted0, %entry ]306 %p0offseted = getelementptr i8, ptr %p0, i64 -4307 %p1offseted = getelementptr i8, ptr %p1, i64 -4308 %size0 = call i64 @llvm.objectsize.i64.p0(ptr %p0offseted, i1 false, i1 true, i1 false)309 %size1 = call i64 @llvm.objectsize.i64.p0(ptr %p1offseted, i1 false, i1 true, i1 false)310 %size = select i1 %cond, i64 %size0, i64 %size1311 ret i64 %size312}313 314define i64 @chain_pick_negative_offset_with_nullptr(i32 %x) {315; CHECK-LABEL: @chain_pick_negative_offset_with_nullptr(316; CHECK-NEXT: entry:317; CHECK-NEXT: [[ARRAY:%.*]] = alloca [4 x i32], align 4318; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0319; CHECK-NEXT: [[P:%.*]] = getelementptr i8, ptr [[ARRAY]], i64 8320; CHECK-NEXT: [[COND:%.*]] = select i1 [[C]], ptr [[P]], ptr null321; CHECK-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[COND]], i64 8322; CHECK-NEXT: [[COND6:%.*]] = select i1 [[C]], ptr [[P4]], ptr null323; CHECK-NEXT: [[P7:%.*]] = getelementptr i8, ptr [[COND6]], i64 -4324; CHECK-NEXT: ret i64 4325;326entry:327 %array = alloca [4 x i32]328 %c = icmp eq i32 %x, 0329 %p = getelementptr i8, ptr %array, i64 8330 %cond = select i1 %c, ptr %p, ptr null331 %p4 = getelementptr i8, ptr %cond, i64 8332 %cond6 = select i1 %c, ptr %p4, ptr null333 %p7 = getelementptr i8, ptr %cond6, i64 -4334 %size = call i64 @llvm.objectsize.i64.p0(ptr %p7, i1 false, i1 false, i1 false)335 ret i64 %size336}337 338 339define i64 @negative_offset_dynamic_eval(i32 %x, i64 %i) {340; CHECK-LABEL: @negative_offset_dynamic_eval(341; CHECK-NEXT: entry:342; CHECK-NEXT: [[ARRAY1:%.*]] = alloca [4 x i32], align 16343; CHECK-NEXT: [[ARRAY2:%.*]] = alloca [8 x i32], align 16344; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0345; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]346; CHECK: if.then:347; CHECK-NEXT: br label [[IF_END:%.*]]348; CHECK: if.else:349; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[ARRAY2]], i64 16350; CHECK-NEXT: br label [[IF_END]]351; CHECK: if.end:352; CHECK-NEXT: [[TMP0:%.*]] = phi i64 [ 16, [[IF_THEN]] ], [ 32, [[IF_ELSE]] ]353; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, [[IF_THEN]] ], [ 16, [[IF_ELSE]] ]354; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[ARRAY1]], [[IF_THEN]] ], [ [[ADD_PTR]], [[IF_ELSE]] ]355; CHECK-NEXT: [[ADD_PTR2_IDX:%.*]] = mul i64 [[I:%.*]], 4356; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], [[ADD_PTR2_IDX]]357; CHECK-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I]]358; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[TMP0]], [[TMP6]]359; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP0]], [[TMP6]]360; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 0, i64 [[TMP1]]361; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i64 [[TMP3]], -1362; CHECK-NEXT: call void @llvm.assume(i1 [[TMP4]])363; CHECK-NEXT: ret i64 [[TMP3]]364;365entry:366 %array1 = alloca [4 x i32], align 16367 %array2 = alloca [8 x i32], align 16368 %tobool.not = icmp eq i32 %x, 0369 br i1 %tobool.not, label %if.else, label %if.then370 371if.then:372 br label %if.end373 374if.else:375 %add.ptr = getelementptr inbounds i8, ptr %array2, i64 16376 br label %if.end377 378if.end:379 %ptr = phi ptr [ %array1, %if.then ], [ %add.ptr, %if.else ]380 %add.ptr2 = getelementptr inbounds i32, ptr %ptr, i64 %i381 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %add.ptr2, i1 false, i1 true, i1 true)382 ret i64 %objsize383}384 385 386define i64 @outofbound_offset_eval(i32 %x) {387; CHECK-LABEL: @outofbound_offset_eval(388; CHECK-NEXT: entry:389; CHECK-NEXT: [[ARRAY:%.*]] = alloca [4 x i8], align 16390; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0391; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]392; CHECK: if.then:393; CHECK-NEXT: [[ADD_PTR0:%.*]] = getelementptr i8, ptr [[ARRAY]], i64 10394; CHECK-NEXT: br label [[IF_END:%.*]]395; CHECK: if.else:396; CHECK-NEXT: [[ADD_PTR1:%.*]] = getelementptr i8, ptr [[ARRAY]], i64 12397; CHECK-NEXT: br label [[IF_END]]398; CHECK: if.end:399; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[ADD_PTR0]], [[IF_THEN]] ], [ [[ADD_PTR1]], [[IF_ELSE]] ]400; CHECK-NEXT: [[ADD_PTR2:%.*]] = getelementptr i8, ptr [[PTR]], i64 -10401; CHECK-NEXT: ret i64 4402;403entry:404 %array = alloca [4 x i8], align 16405 %tobool.not = icmp eq i32 %x, 0406 br i1 %tobool.not, label %if.else, label %if.then407 408if.then:409 %add.ptr0 = getelementptr i8, ptr %array, i64 10410 br label %if.end411 412if.else:413 %add.ptr1 = getelementptr i8, ptr %array, i64 12414 br label %if.end415 416if.end:417 %ptr = phi ptr [ %add.ptr0, %if.then ], [ %add.ptr1, %if.else ]418 %add.ptr2 = getelementptr i8, ptr %ptr, i64 -10419 %objsize = call i64 @llvm.objectsize.i64.p0(ptr %add.ptr2, i1 false, i1 false, i1 false)420 ret i64 %objsize421}422