1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -ipsccp -S %s | FileCheck %s 3 4; A few test cases exposing crashes with the initial range implementation. 5 6@global.2 = external dso_local unnamed_addr constant [25 x i8], align 1 7@global = internal local_unnamed_addr global i32 0, align 4 8@global.3 = internal local_unnamed_addr global i32 0, align 4 9 10define void @main(i8** %arg) { 11; CHECK-LABEL: @main( 12; CHECK-NEXT: bb: 13; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds i8*, i8** [[ARG:%.*]], i64 undef 14; CHECK-NEXT: [[TMP1:%.*]] = load i8*, i8** [[TMP]], align 8 15; CHECK-NEXT: [[TMP2:%.*]] = load i8, i8* [[TMP1]], align 1 16; CHECK-NEXT: [[TMP3:%.*]] = sext i8 [[TMP2]] to i32 17; CHECK-NEXT: [[TMP4:%.*]] = icmp ne i32 [[TMP3]], 45 18; CHECK-NEXT: [[TMP5:%.*]] = select i1 [[TMP4]], i32 2, i32 4 19; CHECK-NEXT: ret void 20; 21bb: 22 %tmp = getelementptr inbounds i8*, i8** %arg, i64 undef 23 %tmp1 = load i8*, i8** %tmp, align 8 24 %tmp2 = load i8, i8* %tmp1, align 1 25 %tmp3 = sext i8 %tmp2 to i32 26 %tmp4 = icmp ne i32 %tmp3, 45 27 %tmp5 = select i1 %tmp4, i32 2, i32 4 28 ret void 29} 30 31define void @ham() local_unnamed_addr { 32; CHECK-LABEL: @ham( 33; CHECK-NEXT: bb: 34; CHECK-NEXT: br label [[BB1:%.*]] 35; CHECK: bb1: 36; CHECK-NEXT: [[TMP:%.*]] = icmp slt i32 undef, 40 37; CHECK-NEXT: br i1 [[TMP]], label [[BB2:%.*]], label [[BB4:%.*]] 38; CHECK: bb2: 39; CHECK-NEXT: br label [[BB7:%.*]] 40; CHECK: bb3: 41; CHECK-NEXT: br label [[BB4]] 42; CHECK: bb4: 43; CHECK-NEXT: [[TMP5:%.*]] = phi i64 [ 0, [[BB1]] ], [ 15, [[BB3:%.*]] ] 44; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[TMP5]], add (i64 xor (i64 ptrtoint ([25 x i8]* @global.2 to i64), i64 -1), i64 1) 45; CHECK-NEXT: unreachable 46; CHECK: bb7: 47; CHECK-NEXT: br label [[BB3]] 48; 49bb: 50 br label %bb1 51 52bb1: ; preds = %bb 53 %tmp = icmp slt i32 undef, 40 54 br i1 %tmp, label %bb2, label %bb4 55 56bb2: ; preds = %bb1 57 br label %bb7 58 59bb3: ; preds = %bb7 60 br label %bb4 61 62bb4: ; preds = %bb3, %bb1 63 %tmp5 = phi i64 [ 0, %bb1 ], [ %tmp10, %bb3 ] 64 %tmp6 = add i64 %tmp5, add (i64 xor (i64 ptrtoint ([25 x i8]* @global.2 to i64), i64 -1), i64 1) 65 unreachable 66 67bb7: ; preds = %bb2 68 %tmp8 = add i64 0, 15 69 %tmp9 = add i64 %tmp8, 0 70 %tmp10 = add i64 %tmp9, 0 71 br label %bb3 72} 73 74declare i32 @barney.4() 75 76define void @wobble() { 77; CHECK-LABEL: @wobble( 78; CHECK-NEXT: bb: 79; CHECK-NEXT: [[TMP:%.*]] = load i32, i32* @global, align 4 80; CHECK-NEXT: store i32 [[TMP]], i32* @global.3, align 4 81; CHECK-NEXT: ret void 82; 83bb: 84 %tmp = load i32, i32* @global, align 4 85 store i32 %tmp, i32* @global.3, align 4 86 ret void 87} 88 89define i32 @wobble.5(i32 %arg) { 90bb: 91 %tmp = load i32, i32* @global.3, align 4 92 %tmp1 = sdiv i32 0, %tmp 93 ret i32 %tmp1 94} 95 96define void @eggs() { 97; CHECK-LABEL: @eggs( 98; CHECK-NEXT: bb: 99; CHECK-NEXT: br label [[BB1:%.*]] 100; CHECK: bb1: 101; CHECK-NEXT: [[TMP:%.*]] = phi i32 [ 0, [[BB:%.*]] ], [ [[TMP2:%.*]], [[BB1]] ] 102; CHECK-NEXT: [[TMP2]] = add nsw i32 [[TMP]], 1 103; CHECK-NEXT: [[TMP3:%.*]] = call i32 @barney.4() 104; CHECK-NEXT: [[TMP4:%.*]] = icmp eq i32 [[TMP3]], 1 105; CHECK-NEXT: br i1 [[TMP4]], label [[BB1]], label [[BB5:%.*]] 106; CHECK: bb5: 107; CHECK-NEXT: store i32 [[TMP2]], i32* @global, align 4 108; CHECK-NEXT: ret void 109; 110bb: 111 br label %bb1 112 113bb1: ; preds = %bb1, %bb 114 %tmp = phi i32 [ 0, %bb ], [ %tmp2, %bb1 ] 115 %tmp2 = add nsw i32 %tmp, 1 116 %tmp3 = call i32 @barney.4() 117 %tmp4 = icmp eq i32 %tmp3, 1 118 br i1 %tmp4, label %bb1, label %bb5 119 120bb5: ; preds = %bb1 121 store i32 %tmp2, i32* @global, align 4 122 ret void 123} 124 125declare i32* @bar(i32) local_unnamed_addr #3 126 127; Function Attrs: nounwind ssp uwtable 128define { i8, i32* } @struct_crash(i32 %BitWidth) local_unnamed_addr #0 align 2 { 129; CHECK-LABEL: @struct_crash( 130; CHECK-NEXT: entry: 131; CHECK-NEXT: switch i32 [[BITWIDTH:%.*]], label [[IF_END:%.*]] [ 132; CHECK-NEXT: i32 1, label [[CLEANUP:%.*]] 133; CHECK-NEXT: i32 8, label [[SW_BB1_I:%.*]] 134; CHECK-NEXT: ] 135; CHECK: sw.bb1.i: 136; CHECK-NEXT: br label [[CLEANUP]] 137; CHECK: if.end: 138; CHECK-NEXT: [[CALL_I:%.*]] = tail call i32* @bar(i32 [[BITWIDTH]]) 139; CHECK-NEXT: br label [[CLEANUP]] 140; CHECK: cleanup: 141; CHECK-NEXT: [[V1:%.*]] = phi i32* [ [[CALL_I]], [[IF_END]] ], [ null, [[SW_BB1_I]] ], [ null, [[ENTRY:%.*]] ] 142; CHECK-NEXT: [[V2:%.*]] = phi i8 [ 0, [[IF_END]] ], [ 3, [[SW_BB1_I]] ], [ 2, [[ENTRY]] ] 143; CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue { i8, i32* } undef, i8 [[V2]], 0 144; CHECK-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue { i8, i32* } [[DOTFCA_0_INSERT]], i32* [[V1]], 1 145; CHECK-NEXT: ret { i8, i32* } [[DOTFCA_1_INSERT]] 146; 147entry: 148 switch i32 %BitWidth, label %if.end [ 149 i32 1, label %cleanup 150 i32 8, label %sw.bb1.i 151 ] 152 153sw.bb1.i: ; preds = %entry 154 br label %cleanup 155 156if.end: ; preds = %entry 157 %call.i = tail call i32* @bar(i32 %BitWidth) 158 br label %cleanup 159 160cleanup: ; preds = %entry, %sw.bb1.i, %sw.bb2.i, %sw.bb3.i, %sw.bb4.i, %sw.bb5.i, %if.end 161 %v1 = phi i32* [ %call.i, %if.end ], [ null, %sw.bb1.i ], [ null, %entry ] 162 %v2 = phi i8 [ 0, %if.end ], [ 3, %sw.bb1.i ], [ 2, %entry ] 163 %.fca.0.insert = insertvalue { i8, i32* } undef, i8 %v2, 0 164 %.fca.1.insert = insertvalue { i8, i32* } %.fca.0.insert, i32* %v1, 1 165 ret { i8, i32* } %.fca.1.insert 166} 167 168define i64 @crash_ctpop(i1 %cond, i32* %addr) { 169; CHECK-LABEL: @crash_ctpop( 170; CHECK-NEXT: entry: 171; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]] 172; CHECK: if.then: 173; CHECK-NEXT: ret i64 0 174; CHECK: if.else: 175; CHECK-NEXT: [[LV:%.*]] = load i32, i32* [[ADDR:%.*]], align 8 176; CHECK-NEXT: [[ANDV:%.*]] = and i32 [[LV]], 16777215 177; CHECK-NEXT: [[TRUNCV:%.*]] = zext i32 [[ANDV]] to i64 178; CHECK-NEXT: [[RES:%.*]] = tail call i64 @llvm.ctpop.i64(i64 [[TRUNCV]]) 179; CHECK-NEXT: ret i64 [[RES]] 180; 181entry: 182 br i1 %cond, label %if.then, label %if.else 183 184if.then: ; preds = %entry 185 ret i64 0 186 187if.else: ; preds = %entry 188 %lv = load i32, i32* %addr, align 8 189 %andv = and i32 %lv, 16777215 190 %truncv = zext i32 %andv to i64 191 %res = tail call i64 @llvm.ctpop.i64(i64 %truncv) 192 ret i64 %res 193} 194 195declare i64 @llvm.ctpop.i64(i64) 196