1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals all --version 5 2; RUN: opt < %s -passes='bounds-checking<trap;merge>' -S | FileCheck %s --check-prefixes=TR 3; RUN: opt < %s -passes='bounds-checking<rt;merge>' -S | FileCheck %s --check-prefixes=RT 4 5; RUN: opt < %s -passes=bounds-checking -S | FileCheck %s --check-prefixes=TR-NOMERGE 6; RUN: opt < %s -passes='bounds-checking<trap>' -S | FileCheck %s --check-prefixes=TR-NOMERGE 7; RUN: opt < %s -passes='bounds-checking<rt>' -S | FileCheck %s --check-prefixes=RT-NOMERGE 8; RUN: opt < %s -passes='bounds-checking<rt-abort>' -S | FileCheck %s --check-prefixes=RTABORT-NOMERGE 9; RUN: opt < %s -passes='bounds-checking<min-rt>' -S | FileCheck %s --check-prefixes=MINRT-NOMERGE 10; RUN: opt < %s -passes='bounds-checking<min-rt-abort>' -S | FileCheck %s --check-prefixes=MINRTABORT-NOMERGE 11; 12; RUN: opt < %s -passes='bounds-checking<trap;guard=3>' -S | FileCheck %s --check-prefixes=TR-GUARD-COMMON,TR-GUARD-THREE 13; RUN: opt < %s -passes='bounds-checking<trap;guard=13>' -S | FileCheck %s --check-prefixes=TR-GUARD-COMMON,TR-GUARD-THIRTEEN 14; RUN: opt < %s -passes='bounds-checking<rt;guard=-5>' -S | FileCheck %s --check-prefixes=RT-GUARD 15target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 16 17define void @f1(i64 %x) nounwind { 18; TR-LABEL: define void @f1( 19; TR-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 20; TR-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 21; TR-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 22; TR-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 23; TR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 24; TR-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 25; TR-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 26; TR-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]] 27; TR: [[BB7]]: 28; TR-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4 29; TR-NEXT: ret void 30; TR: [[TRAP]]: 31; TR-NEXT: call void @llvm.trap() #[[ATTR2:[0-9]+]], !nosanitize [[META0]] 32; TR-NEXT: unreachable, !nosanitize [[META0]] 33; 34; RT-LABEL: define void @f1( 35; RT-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 36; RT-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 37; RT-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 38; RT-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 39; RT-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 40; RT-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 41; RT-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 42; RT-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]] 43; RT: [[BB7]]: 44; RT-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4 45; RT-NEXT: ret void 46; RT: [[TRAP]]: 47; RT-NEXT: call void @__ubsan_handle_local_out_of_bounds() #[[ATTR0]], !nosanitize [[META0]] 48; RT-NEXT: br label %[[BB7]], !nosanitize [[META0]] 49; 50; TR-NOMERGE-LABEL: define void @f1( 51; TR-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 52; TR-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 53; TR-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 54; TR-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 55; TR-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 56; TR-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 57; TR-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 58; TR-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]] 59; TR-NOMERGE: [[BB7]]: 60; TR-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4 61; TR-NOMERGE-NEXT: ret void 62; TR-NOMERGE: [[TRAP]]: 63; TR-NOMERGE-NEXT: call void @llvm.ubsantrap(i8 3) #[[ATTR2:[0-9]+]], !nosanitize [[META0]] 64; TR-NOMERGE-NEXT: unreachable, !nosanitize [[META0]] 65; 66; RT-NOMERGE-LABEL: define void @f1( 67; RT-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 68; RT-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 69; RT-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 70; RT-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 71; RT-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 72; RT-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 73; RT-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 74; RT-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]] 75; RT-NOMERGE: [[BB7]]: 76; RT-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4 77; RT-NOMERGE-NEXT: ret void 78; RT-NOMERGE: [[TRAP]]: 79; RT-NOMERGE-NEXT: call void @__ubsan_handle_local_out_of_bounds() #[[ATTR1:[0-9]+]], !nosanitize [[META0]] 80; RT-NOMERGE-NEXT: br label %[[BB7]], !nosanitize [[META0]] 81; 82; RTABORT-NOMERGE-LABEL: define void @f1( 83; RTABORT-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 84; RTABORT-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 85; RTABORT-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 86; RTABORT-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 87; RTABORT-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 88; RTABORT-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 89; RTABORT-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 90; RTABORT-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]] 91; RTABORT-NOMERGE: [[BB7]]: 92; RTABORT-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4 93; RTABORT-NOMERGE-NEXT: ret void 94; RTABORT-NOMERGE: [[TRAP]]: 95; RTABORT-NOMERGE-NEXT: call void @__ubsan_handle_local_out_of_bounds_abort() #[[ATTR2:[0-9]+]], !nosanitize [[META0]] 96; RTABORT-NOMERGE-NEXT: unreachable, !nosanitize [[META0]] 97; 98; MINRT-NOMERGE-LABEL: define void @f1( 99; MINRT-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 100; MINRT-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 101; MINRT-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 102; MINRT-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 103; MINRT-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 104; MINRT-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 105; MINRT-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 106; MINRT-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]] 107; MINRT-NOMERGE: [[BB7]]: 108; MINRT-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4 109; MINRT-NOMERGE-NEXT: ret void 110; MINRT-NOMERGE: [[TRAP]]: 111; MINRT-NOMERGE-NEXT: call void @__ubsan_handle_local_out_of_bounds_minimal() #[[ATTR1:[0-9]+]], !nosanitize [[META0]] 112; MINRT-NOMERGE-NEXT: br label %[[BB7]], !nosanitize [[META0]] 113; 114; MINRTABORT-NOMERGE-LABEL: define void @f1( 115; MINRTABORT-NOMERGE-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 116; MINRTABORT-NOMERGE-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 117; MINRTABORT-NOMERGE-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 118; MINRTABORT-NOMERGE-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 119; MINRTABORT-NOMERGE-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 120; MINRTABORT-NOMERGE-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 121; MINRTABORT-NOMERGE-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 122; MINRTABORT-NOMERGE-NEXT: br i1 [[TMP6]], label %[[TRAP:.*]], label %[[BB7:.*]] 123; MINRTABORT-NOMERGE: [[BB7]]: 124; MINRTABORT-NOMERGE-NEXT: [[TMP8:%.*]] = load i128, ptr [[TMP2]], align 4 125; MINRTABORT-NOMERGE-NEXT: ret void 126; MINRTABORT-NOMERGE: [[TRAP]]: 127; MINRTABORT-NOMERGE-NEXT: call void @__ubsan_handle_local_out_of_bounds_minimal_abort() #[[ATTR2:[0-9]+]], !nosanitize [[META0]] 128; MINRTABORT-NOMERGE-NEXT: unreachable, !nosanitize [[META0]] 129; 130; TR-GUARD-COMMON-LABEL: define void @f1( 131; TR-GUARD-COMMON-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 132; TR-GUARD-COMMON-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 133; TR-GUARD-COMMON-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 134; TR-GUARD-COMMON-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 135; TR-GUARD-COMMON-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 136; TR-GUARD-COMMON-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 137; TR-GUARD-COMMON-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 138; 139; TR-GUARD-THREE: [[TMP7:%.*]] = call i1 @llvm.allow.ubsan.check(i8 3), !nosanitize [[META0]] 140; TR-GUARD-THIRTEEN: [[TMP7:%.*]] = call i1 @llvm.allow.ubsan.check(i8 13), !nosanitize [[META0]] 141; 142; TR-GUARD-COMMON: [[TMP8:%.*]] = and i1 [[TMP6]], [[TMP7]], !nosanitize [[META0]] 143; TR-GUARD-COMMON-NEXT: br i1 [[TMP8]], label %[[TRAP:.*]], label %[[BB9:.*]] 144; TR-GUARD-COMMON: [[BB9]]: 145; TR-GUARD-COMMON-NEXT: [[TMP10:%.*]] = load i128, ptr [[TMP2]], align 4 146; TR-GUARD-COMMON-NEXT: ret void 147; TR-GUARD-COMMON: [[TRAP]]: 148; 149; TR-GUARD-THREE: call void @llvm.ubsantrap(i8 3) #[[ATTR3:[0-9]+]], !nosanitize [[META0]] 150; TR-GUARD-THIRTEEN: call void @llvm.ubsantrap(i8 13) #[[ATTR3:[0-9]+]], !nosanitize [[META0]] 151; 152; TR-GUARD-COMMON: unreachable, !nosanitize [[META0]] 153; 154; RT-GUARD-LABEL: define void @f1( 155; RT-GUARD-SAME: i64 [[X:%.*]]) #[[ATTR0:[0-9]+]] { 156; RT-GUARD-NEXT: [[TMP1:%.*]] = mul i64 16, [[X]] 157; RT-GUARD-NEXT: [[TMP2:%.*]] = alloca i128, i64 [[X]], align 8 158; RT-GUARD-NEXT: [[TMP3:%.*]] = sub i64 [[TMP1]], 0, !nosanitize [[META0:![0-9]+]] 159; RT-GUARD-NEXT: [[TMP4:%.*]] = icmp ult i64 [[TMP3]], 16, !nosanitize [[META0]] 160; RT-GUARD-NEXT: [[TMP5:%.*]] = or i1 false, [[TMP4]], !nosanitize [[META0]] 161; RT-GUARD-NEXT: [[TMP6:%.*]] = or i1 false, [[TMP5]], !nosanitize [[META0]] 162; RT-GUARD-NEXT: [[TMP7:%.*]] = call i1 @llvm.allow.ubsan.check(i8 -5), !nosanitize [[META0]] 163; RT-GUARD-NEXT: [[TMP8:%.*]] = and i1 [[TMP6]], [[TMP7]], !nosanitize [[META0]] 164; RT-GUARD-NEXT: br i1 [[TMP8]], label %[[TRAP:.*]], label %[[BB9:.*]] 165; RT-GUARD: [[BB9]]: 166; RT-GUARD-NEXT: [[TMP10:%.*]] = load i128, ptr [[TMP2]], align 4 167; RT-GUARD-NEXT: ret void 168; RT-GUARD: [[TRAP]]: 169; RT-GUARD-NEXT: call void @__ubsan_handle_local_out_of_bounds() #[[ATTR2:[0-9]+]], !nosanitize [[META0]] 170; RT-GUARD-NEXT: br label %[[BB9]], !nosanitize [[META0]] 171; 172 %1 = alloca i128, i64 %x 173 %3 = load i128, ptr %1, align 4 174 ret void 175} 176 177;. 178; TR: attributes #[[ATTR0]] = { nounwind } 179; TR: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind memory(inaccessiblemem: write) } 180; TR: attributes #[[ATTR2]] = { noreturn nounwind } 181;. 182; RT: attributes #[[ATTR0]] = { nounwind } 183;. 184; TR-NOMERGE: attributes #[[ATTR0]] = { nounwind } 185; TR-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { cold noreturn nounwind } 186; TR-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind } 187;. 188; RT-NOMERGE: attributes #[[ATTR0]] = { nounwind } 189; RT-NOMERGE: attributes #[[ATTR1]] = { nomerge nounwind } 190;. 191; RTABORT-NOMERGE: attributes #[[ATTR0]] = { nounwind } 192; RTABORT-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { noreturn nounwind } 193; RTABORT-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind } 194;. 195; MINRT-NOMERGE: attributes #[[ATTR0]] = { nounwind } 196; MINRT-NOMERGE: attributes #[[ATTR1]] = { nomerge nounwind } 197;. 198; MINRTABORT-NOMERGE: attributes #[[ATTR0]] = { nounwind } 199; MINRTABORT-NOMERGE: attributes #[[ATTR1:[0-9]+]] = { noreturn nounwind } 200; MINRTABORT-NOMERGE: attributes #[[ATTR2]] = { nomerge noreturn nounwind } 201;. 202; TR-GUARD: attributes #[[ATTR0]] = { nounwind } 203; TR-GUARD: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) } 204; TR-GUARD: attributes #[[ATTR2:[0-9]+]] = { cold noreturn nounwind } 205; TR-GUARD: attributes #[[ATTR3]] = { nomerge noreturn nounwind } 206;. 207; RT-GUARD: attributes #[[ATTR0]] = { nounwind } 208; RT-GUARD: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: write) } 209; RT-GUARD: attributes #[[ATTR2]] = { nomerge nounwind } 210;. 211; TR: [[META0]] = !{} 212;. 213; RT: [[META0]] = !{} 214;. 215; TR-NOMERGE: [[META0]] = !{} 216;. 217; RT-NOMERGE: [[META0]] = !{} 218;. 219; RTABORT-NOMERGE: [[META0]] = !{} 220;. 221; MINRT-NOMERGE: [[META0]] = !{} 222;. 223; MINRTABORT-NOMERGE: [[META0]] = !{} 224;. 225; TR-GUARD: [[META0]] = !{} 226;. 227; RT-GUARD: [[META0]] = !{} 228;. 229