1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes=poison-checking -S -poison-checking-function-local < %s | FileCheck %s 3 4; This file contains tests to exercise the custom flag validation rules 5 6define i32 @add_noflags(i32 %a, i32 %b) { 7; CHECK-LABEL: @add_noflags( 8; CHECK-NEXT: [[RES:%.*]] = add i32 [[A:%.*]], [[B:%.*]] 9; CHECK-NEXT: ret i32 [[RES]] 10; 11 %res = add i32 %a, %b 12 ret i32 %res 13} 14 15define i32 @add_nsw(i32 %a, i32 %b) { 16; CHECK-LABEL: @add_nsw( 17; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 18; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 19; CHECK-NEXT: [[RES:%.*]] = add nsw i32 [[A]], [[B]] 20; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 21; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) 22; CHECK-NEXT: ret i32 [[RES]] 23; 24 %res = add nsw i32 %a, %b 25 ret i32 %res 26} 27 28define i32 @add_nuw(i32 %a, i32 %b) { 29; CHECK-LABEL: @add_nuw( 30; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 31; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 32; CHECK-NEXT: [[RES:%.*]] = add nuw i32 [[A]], [[B]] 33; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 34; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) 35; CHECK-NEXT: ret i32 [[RES]] 36; 37 %res = add nuw i32 %a, %b 38 ret i32 %res 39} 40 41define i32 @add_nsw_nuw(i32 %a, i32 %b) { 42; CHECK-LABEL: @add_nsw_nuw( 43; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 44; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 45; CHECK-NEXT: [[TMP3:%.*]] = call { i32, i1 } @llvm.uadd.with.overflow.i32(i32 [[A]], i32 [[B]]) 46; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1 47; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]] 48; CHECK-NEXT: [[RES:%.*]] = add nuw nsw i32 [[A]], [[B]] 49; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP5]], true 50; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP6]]) 51; CHECK-NEXT: ret i32 [[RES]] 52; 53 %res = add nsw nuw i32 %a, %b 54 ret i32 %res 55} 56 57define i32 @sub_noflags(i32 %a, i32 %b) { 58; CHECK-LABEL: @sub_noflags( 59; CHECK-NEXT: [[RES:%.*]] = sub i32 [[A:%.*]], [[B:%.*]] 60; CHECK-NEXT: ret i32 [[RES]] 61; 62 %res = sub i32 %a, %b 63 ret i32 %res 64} 65 66define i32 @sub_nsw(i32 %a, i32 %b) { 67; CHECK-LABEL: @sub_nsw( 68; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 69; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 70; CHECK-NEXT: [[RES:%.*]] = sub nsw i32 [[A]], [[B]] 71; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 72; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) 73; CHECK-NEXT: ret i32 [[RES]] 74; 75 %res = sub nsw i32 %a, %b 76 ret i32 %res 77} 78 79define i32 @sub_nuw(i32 %a, i32 %b) { 80; CHECK-LABEL: @sub_nuw( 81; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 82; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 83; CHECK-NEXT: [[RES:%.*]] = sub nuw i32 [[A]], [[B]] 84; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 85; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) 86; CHECK-NEXT: ret i32 [[RES]] 87; 88 %res = sub nuw i32 %a, %b 89 ret i32 %res 90} 91 92define i32 @sub_nsw_nuw(i32 %a, i32 %b) { 93; CHECK-LABEL: @sub_nsw_nuw( 94; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.ssub.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 95; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 96; CHECK-NEXT: [[TMP3:%.*]] = call { i32, i1 } @llvm.usub.with.overflow.i32(i32 [[A]], i32 [[B]]) 97; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1 98; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]] 99; CHECK-NEXT: [[RES:%.*]] = sub nuw nsw i32 [[A]], [[B]] 100; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP5]], true 101; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP6]]) 102; CHECK-NEXT: ret i32 [[RES]] 103; 104 %res = sub nsw nuw i32 %a, %b 105 ret i32 %res 106} 107 108define i32 @mul_noflags(i32 %a, i32 %b) { 109; CHECK-LABEL: @mul_noflags( 110; CHECK-NEXT: [[RES:%.*]] = mul i32 [[A:%.*]], [[B:%.*]] 111; CHECK-NEXT: ret i32 [[RES]] 112; 113 %res = mul i32 %a, %b 114 ret i32 %res 115} 116 117define i32 @mul_nsw(i32 %a, i32 %b) { 118; CHECK-LABEL: @mul_nsw( 119; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 120; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 121; CHECK-NEXT: [[RES:%.*]] = mul nsw i32 [[A]], [[B]] 122; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 123; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) 124; CHECK-NEXT: ret i32 [[RES]] 125; 126 %res = mul nsw i32 %a, %b 127 ret i32 %res 128} 129 130define i32 @mul_nuw(i32 %a, i32 %b) { 131; CHECK-LABEL: @mul_nuw( 132; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 133; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 134; CHECK-NEXT: [[RES:%.*]] = mul nuw i32 [[A]], [[B]] 135; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 136; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) 137; CHECK-NEXT: ret i32 [[RES]] 138; 139 %res = mul nuw i32 %a, %b 140 ret i32 %res 141} 142 143define i32 @mul_nsw_nuw(i32 %a, i32 %b) { 144; CHECK-LABEL: @mul_nsw_nuw( 145; CHECK-NEXT: [[TMP1:%.*]] = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 [[A:%.*]], i32 [[B:%.*]]) 146; CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP1]], 1 147; CHECK-NEXT: [[TMP3:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[A]], i32 [[B]]) 148; CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1 149; CHECK-NEXT: [[TMP5:%.*]] = or i1 [[TMP2]], [[TMP4]] 150; CHECK-NEXT: [[RES:%.*]] = mul nuw nsw i32 [[A]], [[B]] 151; CHECK-NEXT: [[TMP6:%.*]] = xor i1 [[TMP5]], true 152; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP6]]) 153; CHECK-NEXT: ret i32 [[RES]] 154; 155 %res = mul nsw nuw i32 %a, %b 156 ret i32 %res 157} 158 159define i32 @sdiv_noflags(i32 %a, i32 %b) { 160; CHECK-LABEL: @sdiv_noflags( 161; CHECK-NEXT: [[RES:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]] 162; CHECK-NEXT: ret i32 [[RES]] 163; 164 %res = sdiv i32 %a, %b 165 ret i32 %res 166} 167 168define i32 @sdiv_exact(i32 %a, i32 %b) { 169; CHECK-LABEL: @sdiv_exact( 170; CHECK-NEXT: [[TMP1:%.*]] = srem i32 [[A:%.*]], [[B:%.*]] 171; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 172; CHECK-NEXT: [[RES:%.*]] = sdiv exact i32 [[A]], [[B]] 173; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 174; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) 175; CHECK-NEXT: ret i32 [[RES]] 176; 177 %res = sdiv exact i32 %a, %b 178 ret i32 %res 179} 180 181define i32 @udiv_noflags(i32 %a, i32 %b) { 182; CHECK-LABEL: @udiv_noflags( 183; CHECK-NEXT: [[RES:%.*]] = udiv i32 [[A:%.*]], [[B:%.*]] 184; CHECK-NEXT: ret i32 [[RES]] 185; 186 %res = udiv i32 %a, %b 187 ret i32 %res 188} 189 190define i32 @udiv_exact(i32 %a, i32 %b) { 191; CHECK-LABEL: @udiv_exact( 192; CHECK-NEXT: [[TMP1:%.*]] = urem i32 [[A:%.*]], [[B:%.*]] 193; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 194; CHECK-NEXT: [[RES:%.*]] = udiv exact i32 [[A]], [[B]] 195; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true 196; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) 197; CHECK-NEXT: ret i32 [[RES]] 198; 199 %res = udiv exact i32 %a, %b 200 ret i32 %res 201} 202 203define i32 @ashr_noflags(i32 %a, i32 %b) { 204; CHECK-LABEL: @ashr_noflags( 205; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32 206; CHECK-NEXT: [[RES:%.*]] = ashr i32 [[A:%.*]], [[B]] 207; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 208; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 209; CHECK-NEXT: ret i32 [[RES]] 210; 211 %res = ashr i32 %a, %b 212 ret i32 %res 213} 214 215define i32 @ashr_exact(i32 %a, i32 %b) { 216; CHECK-LABEL: @ashr_exact( 217; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32 218; CHECK-NEXT: [[RES:%.*]] = ashr exact i32 [[A:%.*]], [[B]] 219; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 220; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 221; CHECK-NEXT: ret i32 [[RES]] 222; 223 %res = ashr exact i32 %a, %b 224 ret i32 %res 225} 226 227define i32 @lshr_noflags(i32 %a, i32 %b) { 228; CHECK-LABEL: @lshr_noflags( 229; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32 230; CHECK-NEXT: [[RES:%.*]] = lshr i32 [[A:%.*]], [[B]] 231; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 232; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 233; CHECK-NEXT: ret i32 [[RES]] 234; 235 %res = lshr i32 %a, %b 236 ret i32 %res 237} 238 239define i32 @lshr_exact(i32 %a, i32 %b) { 240; CHECK-LABEL: @lshr_exact( 241; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32 242; CHECK-NEXT: [[RES:%.*]] = lshr exact i32 [[A:%.*]], [[B]] 243; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 244; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 245; CHECK-NEXT: ret i32 [[RES]] 246; 247 %res = lshr exact i32 %a, %b 248 ret i32 %res 249} 250 251define i32 @shl_noflags(i32 %a, i32 %b) { 252; CHECK-LABEL: @shl_noflags( 253; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32 254; CHECK-NEXT: [[RES:%.*]] = shl i32 [[A:%.*]], [[B]] 255; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 256; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 257; CHECK-NEXT: ret i32 [[RES]] 258; 259 %res = shl i32 %a, %b 260 ret i32 %res 261} 262 263define i32 @shl_nsw(i32 %a, i32 %b) { 264; CHECK-LABEL: @shl_nsw( 265; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32 266; CHECK-NEXT: [[RES:%.*]] = shl nsw i32 [[A:%.*]], [[B]] 267; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 268; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 269; CHECK-NEXT: ret i32 [[RES]] 270; 271 %res = shl nsw i32 %a, %b 272 ret i32 %res 273} 274 275define i32 @shl_nuw(i32 %a, i32 %b) { 276; CHECK-LABEL: @shl_nuw( 277; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32 278; CHECK-NEXT: [[RES:%.*]] = shl nuw i32 [[A:%.*]], [[B]] 279; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 280; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 281; CHECK-NEXT: ret i32 [[RES]] 282; 283 %res = shl nuw i32 %a, %b 284 ret i32 %res 285} 286 287define i32 @shl_nsw_nuw(i32 %a, i32 %b) { 288; CHECK-LABEL: @shl_nsw_nuw( 289; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[B:%.*]], 32 290; CHECK-NEXT: [[RES:%.*]] = shl nuw nsw i32 [[A:%.*]], [[B]] 291; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 292; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 293; CHECK-NEXT: ret i32 [[RES]] 294; 295 %res = shl nsw nuw i32 %a, %b 296 ret i32 %res 297} 298 299define i32 @extractelement(<4 x i32> %v, i32 %idx) { 300; CHECK-LABEL: @extractelement( 301; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[IDX:%.*]], 4 302; CHECK-NEXT: [[RES:%.*]] = extractelement <4 x i32> [[V:%.*]], i32 [[IDX]] 303; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 304; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 305; CHECK-NEXT: ret i32 [[RES]] 306; 307 %res = extractelement <4 x i32> %v, i32 %idx 308 ret i32 %res 309} 310 311define <4 x i32> @insertelement(<4 x i32> %v, i32 %idx, i32 %val) { 312; CHECK-LABEL: @insertelement( 313; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 [[IDX:%.*]], 4 314; CHECK-NEXT: [[RES:%.*]] = insertelement <4 x i32> [[V:%.*]], i32 [[VAL:%.*]], i32 [[IDX]] 315; CHECK-NEXT: [[TMP2:%.*]] = xor i1 [[TMP1]], true 316; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP2]]) 317; CHECK-NEXT: ret <4 x i32> [[RES]] 318; 319 %res = insertelement <4 x i32> %v, i32 %val, i32 %idx 320 ret <4 x i32> %res 321} 322 323