The internal structure used to carry intermediate computations hold
signed values. If an object size happens to overflow signed values, we
can get invalid result, so make sure this situation never happens.
This is not very limitative as static allocation of such large values
should scarcely happen.
422 lines
16 KiB
LLVM
422 lines
16 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -passes=lower-constant-intrinsics -S < %s | FileCheck %s
|
|
|
|
|
|
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
declare dso_local noalias noundef ptr @malloc(i64 noundef) local_unnamed_addr allocsize(0)
|
|
declare i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg)
|
|
|
|
@buffer = dso_local global [4 x i8] zeroinitializer, align 1
|
|
|
|
define dso_local i64 @pick_max(i32 noundef %n) local_unnamed_addr {
|
|
; CHECK-LABEL: @pick_max(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[MALLOCED:%.*]] = call noalias dereferenceable_or_null(8) ptr @malloc(i64 noundef 8)
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MALLOCED]], [[IF_ELSE]] ], [ @buffer, [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: ret i64 8
|
|
;
|
|
entry:
|
|
%cond = icmp eq i32 %n, 0
|
|
br i1 %cond, label %if.else, label %if.end
|
|
|
|
if.else:
|
|
%malloced = call noalias dereferenceable_or_null(8) ptr @malloc(i64 noundef 8)
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p = phi ptr [ %malloced, %if.else ], [ @buffer, %entry ]
|
|
%size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 false, i1 true, i1 false)
|
|
ret i64 %size
|
|
}
|
|
|
|
define dso_local i64 @pick_min(i32 noundef %n) local_unnamed_addr {
|
|
; CHECK-LABEL: @pick_min(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[MALLOCED:%.*]] = call noalias dereferenceable_or_null(8) ptr @malloc(i64 noundef 8)
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[MALLOCED]], [[IF_ELSE]] ], [ @buffer, [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: ret i64 4
|
|
;
|
|
entry:
|
|
%cond = icmp eq i32 %n, 0
|
|
br i1 %cond, label %if.else, label %if.end
|
|
|
|
if.else:
|
|
%malloced = call noalias dereferenceable_or_null(8) ptr @malloc(i64 noundef 8)
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p = phi ptr [ %malloced, %if.else ], [ @buffer, %entry ]
|
|
%size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 true, i1 true, i1 false)
|
|
ret i64 %size
|
|
}
|
|
|
|
define i64 @pick_max_same(i32 %n) {
|
|
; CHECK-LABEL: @pick_max_same(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BUFFER:%.*]] = alloca i8, i64 20, align 1
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[OFFSETED:%.*]] = getelementptr i8, ptr [[BUFFER]], i64 10
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED]], [[IF_ELSE]] ], [ [[BUFFER]], [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: ret i64 20
|
|
;
|
|
entry:
|
|
%buffer = alloca i8, i64 20
|
|
%cond = icmp eq i32 %n, 0
|
|
br i1 %cond, label %if.else, label %if.end
|
|
|
|
if.else:
|
|
%offseted = getelementptr i8, ptr %buffer, i64 10
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p = phi ptr [ %offseted, %if.else ], [ %buffer, %entry ]
|
|
%size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 false, i1 true, i1 false)
|
|
ret i64 %size
|
|
}
|
|
|
|
define i64 @pick_min_same(i32 %n) {
|
|
; CHECK-LABEL: @pick_min_same(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BUFFER:%.*]] = alloca i8, i64 20, align 1
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[OFFSETED:%.*]] = getelementptr i8, ptr [[BUFFER]], i64 10
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED]], [[IF_ELSE]] ], [ [[BUFFER]], [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: ret i64 10
|
|
;
|
|
entry:
|
|
%buffer = alloca i8, i64 20
|
|
%cond = icmp eq i32 %n, 0
|
|
br i1 %cond, label %if.else, label %if.end
|
|
|
|
if.else:
|
|
%offseted = getelementptr i8, ptr %buffer, i64 10
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p = phi ptr [ %offseted, %if.else ], [ %buffer, %entry ]
|
|
%size = call i64 @llvm.objectsize.i64.p0(ptr %p, i1 true, i1 true, i1 false)
|
|
ret i64 %size
|
|
}
|
|
|
|
define dso_local i64 @pick_max_large(i1 %c) local_unnamed_addr {
|
|
; CHECK-LABEL: @pick_max_large(
|
|
; CHECK-NEXT: [[BUFFER:%.*]] = alloca i8, i64 -7, align 1
|
|
; CHECK-NEXT: [[S:%.*]] = select i1 [[C:%.*]], ptr null, ptr [[BUFFER]]
|
|
; CHECK-NEXT: ret i64 -1
|
|
;
|
|
%buffer = alloca i8, i64 -7 ; Actually a very large positive integer
|
|
%s = select i1 %c, ptr null, ptr %buffer
|
|
%objsize = tail call i64 @llvm.objectsize.i64.p0(ptr %s, i1 false, i1 false, i1 false)
|
|
ret i64 %objsize
|
|
|
|
}
|
|
|
|
define dso_local i64 @pick_max_one_oob(i1 %c0, i1 %c1) {
|
|
; CHECK-LABEL: @pick_max_one_oob(
|
|
; CHECK-NEXT: [[P:%.*]] = alloca [2 x i8], align 1
|
|
; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[P_THEN:%.*]] = getelementptr inbounds [2 x i8], ptr [[P]], i64 0, i64 1
|
|
; CHECK-NEXT: br label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[P_ELSE:%.*]] = getelementptr inbounds [2 x i8], ptr [[P]], i64 0, i64 -1
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P_END:%.*]] = phi ptr [ [[P_ELSE]], [[IF_ELSE]] ], [ [[P_THEN]], [[IF_THEN]] ]
|
|
; CHECK-NEXT: [[OBJSIZE:%.*]] = select i1 [[C1:%.*]], i64 1, i64 0
|
|
; CHECK-NEXT: ret i64 [[OBJSIZE]]
|
|
;
|
|
%p = alloca [2 x i8], align 1
|
|
br i1 %c0, label %if.then, label %if.else
|
|
|
|
if.then:
|
|
%p.then = getelementptr inbounds [2 x i8], ptr %p, i64 0, i64 1
|
|
br label %if.end
|
|
|
|
if.else:
|
|
%p.else = getelementptr inbounds [2 x i8], ptr %p, i64 0, i64 -1
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p.end = phi ptr [%p.else, %if.else], [%p.then, %if.then]
|
|
%objsize.max = call i64 @llvm.objectsize.i64.p0(ptr %p.end, i1 false, i1 true, i1 false)
|
|
%objsize.min = call i64 @llvm.objectsize.i64.p0(ptr %p.end, i1 true, i1 true, i1 false)
|
|
%objsize = select i1 %c1, i64 %objsize.max, i64 %objsize.min
|
|
ret i64 %objsize
|
|
}
|
|
|
|
|
|
define i64 @pick_negative_offset(i32 %n) {
|
|
; CHECK-LABEL: @pick_negative_offset(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
|
|
; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[BUFFER1:%.*]] = alloca i8, i64 20, align 1
|
|
; CHECK-NEXT: [[OFFSETED1:%.*]] = getelementptr i8, ptr [[BUFFER1]], i64 20
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED1]], [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY:%.*]] ]
|
|
; CHECK-NEXT: [[POFFSETED:%.*]] = getelementptr i8, ptr [[P]], i64 -4
|
|
; CHECK-NEXT: ret i64 4
|
|
;
|
|
entry:
|
|
%buffer0 = alloca i8, i64 20
|
|
%offseted0 = getelementptr i8, ptr %buffer0, i64 20
|
|
%cond = icmp eq i32 %n, 0
|
|
br i1 %cond, label %if.else, label %if.end
|
|
|
|
if.else:
|
|
%buffer1 = alloca i8, i64 20
|
|
%offseted1 = getelementptr i8, ptr %buffer1, i64 20
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p = phi ptr [ %offseted1, %if.else ], [ %offseted0, %entry ]
|
|
%poffseted = getelementptr i8, ptr %p, i64 -4
|
|
%size = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 false, i1 false, i1 false)
|
|
ret i64 %size
|
|
}
|
|
|
|
define i64 @pick_negative_offset_different_width(i32 %n) {
|
|
; CHECK-LABEL: @pick_negative_offset_different_width(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 4, align 1
|
|
; CHECK-NEXT: [[BUFFER1:%.*]] = alloca i8, i64 8, align 1
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 1
|
|
; CHECK-NEXT: br label [[IF_END1:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[OFFSETED1:%.*]] = getelementptr i8, ptr [[BUFFER1]], i64 6
|
|
; CHECK-NEXT: br label [[IF_END1]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P:%.*]] = phi ptr [ [[OFFSETED0]], [[IF_ELSE]] ], [ [[OFFSETED1]], [[IF_END]] ]
|
|
; CHECK-NEXT: [[POFFSETED:%.*]] = getelementptr i8, ptr [[P]], i64 -2
|
|
; CHECK-NEXT: ret i64 5
|
|
;
|
|
entry:
|
|
%buffer0 = alloca i8, i64 4
|
|
%buffer1 = alloca i8, i64 8
|
|
%cond = icmp eq i32 %n, 0
|
|
br i1 %cond, label %if.then, label %if.else
|
|
|
|
if.then:
|
|
%offseted0 = getelementptr i8, ptr %buffer0, i64 1
|
|
br label %if.end
|
|
|
|
if.else:
|
|
%offseted1 = getelementptr i8, ptr %buffer1, i64 6
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p = phi ptr [ %offseted0, %if.then ], [ %offseted1, %if.else ]
|
|
%poffseted = getelementptr i8, ptr %p, i64 -2
|
|
%size = call i64 @llvm.objectsize.i64.p0(ptr %poffseted, i1 false, i1 false, i1 false)
|
|
ret i64 %size
|
|
}
|
|
|
|
define i64 @pick_negative_offset_with_nullptr(i32 %n) {
|
|
; CHECK-LABEL: @pick_negative_offset_with_nullptr(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
|
|
; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P0:%.*]] = phi ptr [ [[OFFSETED0]], [[ENTRY:%.*]] ], [ null, [[IF_ELSE]] ]
|
|
; CHECK-NEXT: [[P1:%.*]] = phi ptr [ null, [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY]] ]
|
|
; CHECK-NEXT: [[P0OFFSETED:%.*]] = getelementptr i8, ptr [[P0]], i64 -4
|
|
; CHECK-NEXT: [[P1OFFSETED:%.*]] = getelementptr i8, ptr [[P1]], i64 -4
|
|
; CHECK-NEXT: ret i64 4
|
|
;
|
|
entry:
|
|
%buffer0 = alloca i8, i64 20
|
|
%offseted0 = getelementptr i8, ptr %buffer0, i64 20
|
|
%cond = icmp eq i32 %n, 0
|
|
br i1 %cond, label %if.else, label %if.end
|
|
|
|
if.else:
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p0 = phi ptr [ %offseted0, %entry ], [ null, %if.else ]
|
|
%p1 = phi ptr [ null, %if.else ], [ %offseted0, %entry ]
|
|
%p0offseted = getelementptr i8, ptr %p0, i64 -4
|
|
%p1offseted = getelementptr i8, ptr %p1, i64 -4
|
|
%size0 = call i64 @llvm.objectsize.i64.p0(ptr %p0offseted, i1 false, i1 false, i1 false)
|
|
%size1 = call i64 @llvm.objectsize.i64.p0(ptr %p1offseted, i1 false, i1 false, i1 false)
|
|
%size = select i1 %cond, i64 %size0, i64 %size1
|
|
ret i64 %size
|
|
}
|
|
|
|
define i64 @pick_negative_offset_with_unsized_nullptr(i32 %n) {
|
|
; CHECK-LABEL: @pick_negative_offset_with_unsized_nullptr(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[BUFFER0:%.*]] = alloca i8, i64 20, align 1
|
|
; CHECK-NEXT: [[OFFSETED0:%.*]] = getelementptr i8, ptr [[BUFFER0]], i64 20
|
|
; CHECK-NEXT: [[COND:%.*]] = icmp eq i32 [[N:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[COND]], label [[IF_ELSE:%.*]], label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[P0:%.*]] = phi ptr [ [[OFFSETED0]], [[ENTRY:%.*]] ], [ null, [[IF_ELSE]] ]
|
|
; CHECK-NEXT: [[P1:%.*]] = phi ptr [ null, [[IF_ELSE]] ], [ [[OFFSETED0]], [[ENTRY]] ]
|
|
; CHECK-NEXT: [[P0OFFSETED:%.*]] = getelementptr i8, ptr [[P0]], i64 -4
|
|
; CHECK-NEXT: [[P1OFFSETED:%.*]] = getelementptr i8, ptr [[P1]], i64 -4
|
|
; CHECK-NEXT: ret i64 -1
|
|
;
|
|
entry:
|
|
%buffer0 = alloca i8, i64 20
|
|
%offseted0 = getelementptr i8, ptr %buffer0, i64 20
|
|
%cond = icmp eq i32 %n, 0
|
|
br i1 %cond, label %if.else, label %if.end
|
|
|
|
if.else:
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%p0 = phi ptr [ %offseted0, %entry ], [ null, %if.else ]
|
|
%p1 = phi ptr [ null, %if.else ], [ %offseted0, %entry ]
|
|
%p0offseted = getelementptr i8, ptr %p0, i64 -4
|
|
%p1offseted = getelementptr i8, ptr %p1, i64 -4
|
|
%size0 = call i64 @llvm.objectsize.i64.p0(ptr %p0offseted, i1 false, i1 true, i1 false)
|
|
%size1 = call i64 @llvm.objectsize.i64.p0(ptr %p1offseted, i1 false, i1 true, i1 false)
|
|
%size = select i1 %cond, i64 %size0, i64 %size1
|
|
ret i64 %size
|
|
}
|
|
|
|
define i64 @chain_pick_negative_offset_with_nullptr(i32 %x) {
|
|
; CHECK-LABEL: @chain_pick_negative_offset_with_nullptr(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ARRAY:%.*]] = alloca [4 x i32], align 4
|
|
; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
; CHECK-NEXT: [[P:%.*]] = getelementptr i8, ptr [[ARRAY]], i64 8
|
|
; CHECK-NEXT: [[COND:%.*]] = select i1 [[C]], ptr [[P]], ptr null
|
|
; CHECK-NEXT: [[P4:%.*]] = getelementptr i8, ptr [[COND]], i64 8
|
|
; CHECK-NEXT: [[COND6:%.*]] = select i1 [[C]], ptr [[P4]], ptr null
|
|
; CHECK-NEXT: [[P7:%.*]] = getelementptr i8, ptr [[COND6]], i64 -4
|
|
; CHECK-NEXT: ret i64 4
|
|
;
|
|
entry:
|
|
%array = alloca [4 x i32]
|
|
%c = icmp eq i32 %x, 0
|
|
%p = getelementptr i8, ptr %array, i64 8
|
|
%cond = select i1 %c, ptr %p, ptr null
|
|
%p4 = getelementptr i8, ptr %cond, i64 8
|
|
%cond6 = select i1 %c, ptr %p4, ptr null
|
|
%p7 = getelementptr i8, ptr %cond6, i64 -4
|
|
%size = call i64 @llvm.objectsize.i64.p0(ptr %p7, i1 false, i1 false, i1 false)
|
|
ret i64 %size
|
|
}
|
|
|
|
|
|
define i64 @negative_offset_dynamic_eval(i32 %x, i64 %i) {
|
|
; CHECK-LABEL: @negative_offset_dynamic_eval(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ARRAY1:%.*]] = alloca [4 x i32], align 16
|
|
; CHECK-NEXT: [[ARRAY2:%.*]] = alloca [8 x i32], align 16
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: br label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[ARRAY2]], i64 16
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[TMP0:%.*]] = phi i64 [ 16, [[IF_THEN]] ], [ 32, [[IF_ELSE]] ]
|
|
; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, [[IF_THEN]] ], [ 16, [[IF_ELSE]] ]
|
|
; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[ARRAY1]], [[IF_THEN]] ], [ [[ADD_PTR]], [[IF_ELSE]] ]
|
|
; CHECK-NEXT: [[ADD_PTR2_IDX:%.*]] = mul i64 [[I:%.*]], 4
|
|
; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], [[ADD_PTR2_IDX]]
|
|
; CHECK-NEXT: [[ADD_PTR2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I]]
|
|
; CHECK-NEXT: [[TMP1:%.*]] = sub i64 [[TMP0]], [[TMP6]]
|
|
; CHECK-NEXT: [[TMP2:%.*]] = icmp ult i64 [[TMP0]], [[TMP6]]
|
|
; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i64 0, i64 [[TMP1]]
|
|
; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i64 [[TMP3]], -1
|
|
; CHECK-NEXT: call void @llvm.assume(i1 [[TMP4]])
|
|
; CHECK-NEXT: ret i64 [[TMP3]]
|
|
;
|
|
entry:
|
|
%array1 = alloca [4 x i32], align 16
|
|
%array2 = alloca [8 x i32], align 16
|
|
%tobool.not = icmp eq i32 %x, 0
|
|
br i1 %tobool.not, label %if.else, label %if.then
|
|
|
|
if.then:
|
|
br label %if.end
|
|
|
|
if.else:
|
|
%add.ptr = getelementptr inbounds i8, ptr %array2, i64 16
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%ptr = phi ptr [ %array1, %if.then ], [ %add.ptr, %if.else ]
|
|
%add.ptr2 = getelementptr inbounds i32, ptr %ptr, i64 %i
|
|
%objsize = call i64 @llvm.objectsize.i64.p0(ptr %add.ptr2, i1 false, i1 true, i1 true)
|
|
ret i64 %objsize
|
|
}
|
|
|
|
|
|
define i64 @outofbound_offset_eval(i32 %x) {
|
|
; CHECK-LABEL: @outofbound_offset_eval(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[ARRAY:%.*]] = alloca [4 x i8], align 16
|
|
; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i32 [[X:%.*]], 0
|
|
; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]
|
|
; CHECK: if.then:
|
|
; CHECK-NEXT: [[ADD_PTR0:%.*]] = getelementptr i8, ptr [[ARRAY]], i64 10
|
|
; CHECK-NEXT: br label [[IF_END:%.*]]
|
|
; CHECK: if.else:
|
|
; CHECK-NEXT: [[ADD_PTR1:%.*]] = getelementptr i8, ptr [[ARRAY]], i64 12
|
|
; CHECK-NEXT: br label [[IF_END]]
|
|
; CHECK: if.end:
|
|
; CHECK-NEXT: [[PTR:%.*]] = phi ptr [ [[ADD_PTR0]], [[IF_THEN]] ], [ [[ADD_PTR1]], [[IF_ELSE]] ]
|
|
; CHECK-NEXT: [[ADD_PTR2:%.*]] = getelementptr i8, ptr [[PTR]], i64 -10
|
|
; CHECK-NEXT: ret i64 4
|
|
;
|
|
entry:
|
|
%array = alloca [4 x i8], align 16
|
|
%tobool.not = icmp eq i32 %x, 0
|
|
br i1 %tobool.not, label %if.else, label %if.then
|
|
|
|
if.then:
|
|
%add.ptr0 = getelementptr i8, ptr %array, i64 10
|
|
br label %if.end
|
|
|
|
if.else:
|
|
%add.ptr1 = getelementptr i8, ptr %array, i64 12
|
|
br label %if.end
|
|
|
|
if.end:
|
|
%ptr = phi ptr [ %add.ptr0, %if.then ], [ %add.ptr1, %if.else ]
|
|
%add.ptr2 = getelementptr i8, ptr %ptr, i64 -10
|
|
%objsize = call i64 @llvm.objectsize.i64.p0(ptr %add.ptr2, i1 false, i1 false, i1 false)
|
|
ret i64 %objsize
|
|
}
|