brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.7 KiB · 7bd2aca Raw
282 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=constraint-elimination -S %s | FileCheck %s3 4; Tests for using inbounds information from GEPs where the GEP only causes UB in the use blocks.5 6declare void @noundef(ptr noundef) willreturn nounwind7declare void @noundef2(ptr noundef)8 9declare void @use(i1)10 11; %start + %n.ext is guaranteed to not overflow (due to inbounds).12; %start + %idx.ext does not overflow if %idx.ext <= %n.ext.13define i1 @inbounds_poison_is_ub_in_use_block_1(ptr %src, i32 %n, i32 %idx) {14; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_1(15; CHECK-NEXT:  entry:16; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i6417; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]18; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]19; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i6420; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]21; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]22; CHECK:       then:23; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])24; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]25; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]26; CHECK:       else:27; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]28; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]29;30entry:31  %n.ext = zext i32 %n to i6432  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext33  %cmp.idx = icmp ult i32 %idx, %n34  %idx.ext = zext i32 %idx to i6435  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext36  br i1 %cmp.idx, label %then, label %else37 38then:39  call void @noundef(ptr %upper)40  %cmp.upper.1 = icmp ule ptr %src.idx, %upper41  ret i1 %cmp.upper.142 43else:44  %cmp.upper.2 = icmp ule ptr %src.idx, %upper45  ret i1 %cmp.upper.246}47 48define i1 @inbounds_poison_is_ub_in_use_block_2(ptr %src, i32 %n, i32 %idx, i1 %c) {49; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_2(50; CHECK-NEXT:  entry:51; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i6452; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]53; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]54; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i6455; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]56; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]57; CHECK:       then:58; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]59; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])60; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]61; CHECK:       else:62; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]63; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]64;65entry:66  %n.ext = zext i32 %n to i6467  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext68  %cmp.idx = icmp ult i32 %idx, %n69  %idx.ext = zext i32 %idx to i6470  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext71  br i1 %cmp.idx, label %then, label %else72 73then:74  %cmp.upper.1 = icmp ule ptr %src.idx, %upper75  call void @noundef(ptr %upper)76  ret i1 %cmp.upper.177 78else:79  %cmp.upper.2 = icmp ule ptr %src.idx, %upper80  ret i1 %cmp.upper.281}82 83declare void @llvm.assume(i1)84 85; %start + %n.ext is guaranteed to not overflow (due to inbounds).86; %start + %idx.ext does not overflow if %idx.ext <= %n.ext.87define i1 @inbounds_poison_is_ub_in_use_block_by_assume(ptr %src, i32 %n, i32 %idx) {88; CHECK-LABEL: @inbounds_poison_is_ub_in_use_block_by_assume(89; CHECK-NEXT:  entry:90; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i6491; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]92; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]93; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i6494; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]95; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]96; CHECK:       then:97; CHECK-NEXT:    [[CMP_NE:%.*]] = icmp ule ptr null, [[UPPER]]98; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_NE]])99; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]100; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]101; CHECK:       else:102; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]103; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]104;105entry:106  %n.ext = zext i32 %n to i64107  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext108  %cmp.idx = icmp ult i32 %idx, %n109  %idx.ext = zext i32 %idx to i64110  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext111  br i1 %cmp.idx, label %then, label %else112 113then:114  %cmp.ne = icmp ule ptr null, %upper115  call void @llvm.assume(i1 %cmp.ne)116  %cmp.upper.1 = icmp ule ptr %src.idx, %upper117  ret i1 %cmp.upper.1118 119else:120  %cmp.upper.2 = icmp ule ptr %src.idx, %upper121  ret i1 %cmp.upper.2122}123 124 125; %start + %n.ext is guaranteed to not overflow (due to inbounds).126; %start + %idx.ext does not overflow if %idx.ext <= %n.ext.127define i1 @inbounds_poison_is_ub_in_in_multiple_use_blocks_1(ptr %src, i32 %n, i32 %idx, i1 %c) {128; CHECK-LABEL: @inbounds_poison_is_ub_in_in_multiple_use_blocks_1(129; CHECK-NEXT:  entry:130; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64131; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]132; CHECK-NEXT:    br i1 [[C:%.*]], label [[CHECK_BB:%.*]], label [[EXIT:%.*]]133; CHECK:       check.bb:134; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])135; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]136; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64137; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]138; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]139; CHECK:       then:140; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])141; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]142; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]143; CHECK:       else:144; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]145; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]146; CHECK:       exit:147; CHECK-NEXT:    ret i1 false148;149entry:150  %n.ext = zext i32 %n to i64151  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext152  br i1 %c, label %check.bb, label %exit153 154check.bb:155  call void @noundef(ptr %upper)156  %cmp.idx = icmp ult i32 %idx, %n157  %idx.ext = zext i32 %idx to i64158  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext159  br i1 %cmp.idx, label %then, label %else160 161then:162  call void @noundef(ptr %upper)163  %cmp.upper.1 = icmp ule ptr %src.idx, %upper164  ret i1 %cmp.upper.1165 166else:167  %cmp.upper.2 = icmp ule ptr %src.idx, %upper168  ret i1 %cmp.upper.2169 170exit:171  ret i1 false172}173 174define i1 @may_exit_before_ub_is_caused(ptr %src, i32 %n, i32 %idx) {175; CHECK-LABEL: @may_exit_before_ub_is_caused(176; CHECK-NEXT:  entry:177; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64178; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]179; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]180; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64181; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]182; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]183; CHECK:       then:184; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]185; CHECK-NEXT:    call void @use(i1 [[CMP_UPPER_1]])186; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])187; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]188; CHECK:       else:189; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]190; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]191;192entry:193  %n.ext = zext i32 %n to i64194  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext195  %cmp.idx = icmp ult i32 %idx, %n196  %idx.ext = zext i32 %idx to i64197  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext198  br i1 %cmp.idx, label %then, label %else199 200then:201  %cmp.upper.1 = icmp ule ptr %src.idx, %upper202  call void @use(i1 %cmp.upper.1);203  call void @noundef(ptr %upper)204  ret i1 %cmp.upper.1205 206else:207  %cmp.upper.2 = icmp ule ptr %src.idx, %upper208  ret i1 %cmp.upper.2209}210 211define i1 @only_UB_in_false_block(ptr %src, i32 %n, i32 %idx) {212; CHECK-LABEL: @only_UB_in_false_block(213; CHECK-NEXT:  entry:214; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64215; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]216; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]217; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64218; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]219; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]220; CHECK:       then:221; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]222; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]223; CHECK:       else:224; CHECK-NEXT:    call void @noundef(ptr [[UPPER]])225; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]226; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]227;228entry:229  %n.ext = zext i32 %n to i64230  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext231  %cmp.idx = icmp ult i32 %idx, %n232  %idx.ext = zext i32 %idx to i64233  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext234  br i1 %cmp.idx, label %then, label %else235 236then:237  %cmp.upper.1 = icmp ule ptr %src.idx, %upper238  ret i1 %cmp.upper.1239 240else:241  call void @noundef(ptr %upper)242  %cmp.upper.2 = icmp ule ptr %src.idx, %upper243  ret i1 %cmp.upper.2244}245 246define i1 @only_ub_by_assume_in_false_block(ptr %src, i32 %n, i32 %idx) {247; CHECK-LABEL: @only_ub_by_assume_in_false_block(248; CHECK-NEXT:  entry:249; CHECK-NEXT:    [[N_EXT:%.*]] = zext i32 [[N:%.*]] to i64250; CHECK-NEXT:    [[UPPER:%.*]] = getelementptr inbounds i32, ptr [[SRC:%.*]], i64 [[N_EXT]]251; CHECK-NEXT:    [[CMP_IDX:%.*]] = icmp ult i32 [[IDX:%.*]], [[N]]252; CHECK-NEXT:    [[IDX_EXT:%.*]] = zext i32 [[IDX]] to i64253; CHECK-NEXT:    [[SRC_IDX:%.*]] = getelementptr i32, ptr [[SRC]], i64 [[IDX_EXT]]254; CHECK-NEXT:    br i1 [[CMP_IDX]], label [[THEN:%.*]], label [[ELSE:%.*]]255; CHECK:       then:256; CHECK-NEXT:    [[CMP_UPPER_1:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]257; CHECK-NEXT:    ret i1 [[CMP_UPPER_1]]258; CHECK:       else:259; CHECK-NEXT:    [[CMP_NE:%.*]] = icmp ule ptr null, [[UPPER]]260; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP_NE]])261; CHECK-NEXT:    [[CMP_UPPER_2:%.*]] = icmp ule ptr [[SRC_IDX]], [[UPPER]]262; CHECK-NEXT:    ret i1 [[CMP_UPPER_2]]263;264entry:265  %n.ext = zext i32 %n to i64266  %upper = getelementptr inbounds i32, ptr %src, i64 %n.ext267  %cmp.idx = icmp ult i32 %idx, %n268  %idx.ext = zext i32 %idx to i64269  %src.idx = getelementptr i32, ptr %src, i64 %idx.ext270  br i1 %cmp.idx, label %then, label %else271 272then:273  %cmp.upper.1 = icmp ule ptr %src.idx, %upper274  ret i1 %cmp.upper.1275 276else:277  %cmp.ne = icmp ule ptr null, %upper278  call void @llvm.assume(i1 %cmp.ne)279  %cmp.upper.2 = icmp ule ptr %src.idx, %upper280  ret i1 %cmp.upper.2281}282