
…generating empty location Fix the regression detected by https://github.com/llvm/llvm-test-suite/pull/188
132 lines
6.1 KiB
LLVM
132 lines
6.1 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 i64 @llvm.objectsize.i64.p0(ptr, i1 immarg, i1 immarg, i1 immarg)
|
|
declare noalias ptr @malloc(i64 noundef) #0
|
|
|
|
define i64 @select_alloc_size(i1 %cond) {
|
|
; CHECK-LABEL: @select_alloc_size(
|
|
; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[COND:%.*]], i64 3, i64 4
|
|
; CHECK-NEXT: [[PTR:%.*]] = alloca i8, i64 [[SIZE]], align 1
|
|
; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i64 4, i64 3
|
|
; CHECK-NEXT: ret i64 [[RES]]
|
|
;
|
|
%size = select i1 %cond, i64 3, i64 4
|
|
%ptr = alloca i8, i64 %size
|
|
%objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false)
|
|
%objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 true, i1 true, i1 false)
|
|
%res = select i1 %cond, i64 %objsize_max, i64 %objsize_min
|
|
ret i64 %res
|
|
}
|
|
|
|
define i64 @select_malloc_size(i1 %cond) {
|
|
; CHECK-LABEL: @select_malloc_size(
|
|
; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[COND:%.*]], i64 3, i64 4
|
|
; CHECK-NEXT: [[PTR:%.*]] = call noalias ptr @malloc(i64 noundef [[SIZE]])
|
|
; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i64 4, i64 3
|
|
; CHECK-NEXT: ret i64 [[RES]]
|
|
;
|
|
%size = select i1 %cond, i64 3, i64 4
|
|
%ptr = call noalias ptr @malloc(i64 noundef %size)
|
|
%objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 false, i1 true, i1 false)
|
|
%objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr, i1 true, i1 true, i1 false)
|
|
%res = select i1 %cond, i64 %objsize_max, i64 %objsize_min
|
|
ret i64 %res
|
|
}
|
|
|
|
define i64 @select_gep_offset(i1 %cond) {
|
|
; CHECK-LABEL: @select_gep_offset(
|
|
; CHECK-NEXT: [[PTR:%.*]] = alloca i8, i64 10, align 1
|
|
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[COND:%.*]], i64 3, i64 4
|
|
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[OFFSET]]
|
|
; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i64 7, i64 6
|
|
; CHECK-NEXT: ret i64 [[RES]]
|
|
;
|
|
%ptr = alloca i8, i64 10
|
|
%offset = select i1 %cond, i64 3, i64 4
|
|
%ptr.slide = getelementptr inbounds i8, ptr %ptr, i64 %offset
|
|
%objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
|
|
%objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
|
|
%res = select i1 %cond, i64 %objsize_max, i64 %objsize_min
|
|
ret i64 %res
|
|
}
|
|
|
|
define i64 @select_gep_neg_offset(i1 %c0, i1 %c1) {
|
|
; CHECK-LABEL: @select_gep_neg_offset(
|
|
; CHECK-NEXT: [[PTR:%.*]] = alloca i8, i64 10, align 1
|
|
; CHECK-NEXT: [[PTR_SLIDE_1:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 5
|
|
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[COND:%.*]], i64 -3, i64 -4
|
|
; CHECK-NEXT: [[PTR_SLIDE_2:%.*]] = getelementptr inbounds i8, ptr [[PTR_SLIDE_1]], i64 [[OFFSET]]
|
|
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1:%.*]], i64 9, i64 8
|
|
; CHECK-NEXT: ret i64 [[RES]]
|
|
;
|
|
%ptr = alloca i8, i64 10
|
|
%ptr.slide.1 = getelementptr inbounds i8, ptr %ptr, i64 5
|
|
%offset = select i1 %c0, i64 -3, i64 -4
|
|
%ptr.slide.2 = getelementptr inbounds i8, ptr %ptr.slide.1, i64 %offset
|
|
%objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide.2, i1 false, i1 true, i1 false)
|
|
%objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide.2, i1 true, i1 true, i1 false)
|
|
%res = select i1 %c1, i64 %objsize_max, i64 %objsize_min
|
|
ret i64 %res
|
|
}
|
|
|
|
define i64 @select_neg_oob_offset(i1 %c0, i1 %c1) {
|
|
; CHECK-LABEL: @select_neg_oob_offset(
|
|
; CHECK-NEXT: [[PTR:%.*]] = alloca i8, i64 10, align 1
|
|
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[C0:%.*]], i64 -3, i64 -4
|
|
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr inbounds i8, ptr [[PTR]], i64 [[OFFSET]]
|
|
; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1:%.*]], i64 -1, i64 0
|
|
; CHECK-NEXT: ret i64 [[RES]]
|
|
;
|
|
%ptr = alloca i8, i64 10
|
|
%offset = select i1 %c0, i64 -3, i64 -4
|
|
%ptr.slide = getelementptr inbounds i8, ptr %ptr, i64 %offset
|
|
%objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
|
|
%objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
|
|
%res = select i1 %c1, i64 %objsize_max, i64 %objsize_min
|
|
ret i64 %res
|
|
}
|
|
|
|
define i64 @select_gep_offsets(i1 %cond) {
|
|
; CHECK-LABEL: @select_gep_offsets(
|
|
; CHECK-NEXT: [[PTR:%.*]] = alloca [10 x i8], i64 2, align 1
|
|
; CHECK-NEXT: [[OFFSET:%.*]] = select i1 [[COND:%.*]], i32 0, i32 1
|
|
; CHECK-NEXT: [[PTR_SLIDE:%.*]] = getelementptr inbounds [10 x i8], ptr [[PTR]], i32 [[OFFSET]], i32 5
|
|
; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i64 15, i64 5
|
|
; CHECK-NEXT: ret i64 [[RES]]
|
|
;
|
|
%ptr = alloca [10 x i8], i64 2
|
|
%offset = select i1 %cond, i32 0, i32 1
|
|
%ptr.slide = getelementptr inbounds [10 x i8], ptr %ptr, i32 %offset, i32 5
|
|
%objsize_max = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 false, i1 true, i1 false)
|
|
%objsize_min = call i64 @llvm.objectsize.i64.p0(ptr %ptr.slide, i1 true, i1 true, i1 false)
|
|
%res = select i1 %cond, i64 %objsize_max, i64 %objsize_min
|
|
ret i64 %res
|
|
}
|
|
|
|
define i64 @select_gep_oob_overapproximated_offsets(i1 %cond) {
|
|
; CHECK-LABEL: @select_gep_oob_overapproximated_offsets(
|
|
; CHECK-NEXT: [[BASE1:%.*]] = alloca [288 x i8], align 16
|
|
; CHECK-NEXT: [[SELECT0:%.*]] = select i1 [[COND:%.*]], i64 -4, i64 -64
|
|
; CHECK-NEXT: [[SELECT1:%.*]] = select i1 [[COND]], i64 16, i64 64
|
|
; CHECK-NEXT: [[GEP0:%.*]] = getelementptr inbounds nuw i8, ptr [[BASE1]], i64 [[SELECT1]]
|
|
; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i8, ptr [[GEP0]], i64 [[SELECT0]]
|
|
; CHECK-NEXT: ret i64 -1
|
|
;
|
|
%base1 = alloca [288 x i8], align 16
|
|
%select0 = select i1 %cond, i64 -4, i64 -64
|
|
%select1 = select i1 %cond, i64 16, i64 64
|
|
; This never actually goes oob, but because we approximate each select
|
|
; independently, this actually ranges in [16 - 64 ; 64 - 4] instead of [64 - 64; 16 - 4]
|
|
%gep0 = getelementptr inbounds nuw i8, ptr %base1, i64 %select1
|
|
%gep1 = getelementptr inbounds i8, ptr %gep0, i64 %select0
|
|
%call = call i64 @llvm.objectsize.i64.p0(ptr %gep1, i1 false, i1 true, i1 false)
|
|
ret i64 %call
|
|
}
|
|
|
|
|
|
attributes #0 = { nounwind allocsize(0) }
|