brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.4 KiB · eaafe6b Raw
667 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt -passes='loop(loop-idiom)' < %s -S | FileCheck %s3 4declare void @other()5declare void @use(ptr)6declare void @usei(i32)7declare void @usel(i64)8 9; size_t basic_strlen(const char* str) {10;     while (*str != '\0') {11;         ++str;12;     }13;     return str - base;14; }15define i64 @valid_basic_strlen(ptr %str) {16; CHECK-LABEL: define i64 @valid_basic_strlen(17; CHECK-SAME: ptr [[STR:%.*]]) {18; CHECK-NEXT:  [[ENTRY:.*]]:19; CHECK-NEXT:    [[STRLEN:%.*]] = call i64 @strlen(ptr [[STR]])20; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[STR]], i64 [[STRLEN]]21; CHECK-NEXT:    br label %[[WHILE_COND:.*]]22; CHECK:       [[WHILE_COND]]:23; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]24; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 125; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 026; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 127; CHECK-NEXT:    br i1 true, label %[[WHILE_END:.*]], label %[[WHILE_COND]]28; CHECK:       [[WHILE_END]]:29; CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[SCEVGEP]] to i6430; CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i6431; CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]32; CHECK-NEXT:    ret i64 [[SUB_PTR_SUB]]33;34entry:35  br label %while.cond36 37while.cond:38  %str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]39  %0 = load i8, ptr %str.addr.0, align 140  %cmp.not = icmp eq i8 %0, 041  %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 142  br i1 %cmp.not, label %while.end, label %while.cond43 44while.end:45  %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i6446  %sub.ptr.rhs.cast = ptrtoint ptr %str to i6447  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast48  ret i64 %sub.ptr.sub49}50 51; int valid_basic_strlen_rotated(const char* str) {52;     const char* base = str;53;     if (!*str) return 0;54;     do {55;         ++str;56;     } while (*str);57;     return str - base;58; }59define i32 @valid_basic_strlen_rotated(ptr %str) {60; CHECK-LABEL: define i32 @valid_basic_strlen_rotated(61; CHECK-SAME: ptr [[STR:%.*]]) {62; CHECK-NEXT:  [[ENTRY:.*]]:63; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR]], align 164; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i8 [[TMP0]], 065; CHECK-NEXT:    br i1 [[TOBOOL_NOT]], label %[[CLEANUP:.*]], label %[[DO_BODY_PREHEADER:.*]]66; CHECK:       [[DO_BODY_PREHEADER]]:67; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[STR]], i64 168; CHECK-NEXT:    [[STRLEN:%.*]] = call i64 @strlen(ptr [[SCEVGEP]])69; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[STRLEN]], 170; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[STR]], i64 [[TMP1]]71; CHECK-NEXT:    br label %[[DO_BODY:.*]]72; CHECK:       [[DO_BODY]]:73; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], %[[DO_BODY]] ], [ [[STR]], %[[DO_BODY_PREHEADER]] ]74; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[STR_ADDR_0]], i64 175; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[INCDEC_PTR]], align 176; CHECK-NEXT:    [[TOBOOL1_NOT:%.*]] = icmp eq i8 [[TMP2]], 077; CHECK-NEXT:    br i1 true, label %[[DO_END:.*]], label %[[DO_BODY]]78; CHECK:       [[DO_END]]:79; CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[SCEVGEP1]] to i6480; CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i6481; CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]82; CHECK-NEXT:    [[CONV:%.*]] = trunc i64 [[SUB_PTR_SUB]] to i3283; CHECK-NEXT:    br label %[[CLEANUP]]84; CHECK:       [[CLEANUP]]:85; CHECK-NEXT:    [[RETVAL_0:%.*]] = phi i32 [ [[CONV]], %[[DO_END]] ], [ 0, %[[ENTRY]] ]86; CHECK-NEXT:    ret i32 [[RETVAL_0]]87;88entry:89  %0 = load i8, ptr %str, align 190  %tobool.not = icmp eq i8 %0, 091  br i1 %tobool.not, label %cleanup, label %do.body92 93do.body:94  %str.addr.0 = phi ptr [ %incdec.ptr, %do.body ], [ %str, %entry ]95  %incdec.ptr = getelementptr inbounds nuw i8, ptr %str.addr.0, i64 196  %1 = load i8, ptr %incdec.ptr, align 197  %tobool1.not = icmp eq i8 %1, 098  br i1 %tobool1.not, label %do.end, label %do.body99 100do.end:101  %sub.ptr.lhs.cast = ptrtoint ptr %incdec.ptr to i64102  %sub.ptr.rhs.cast = ptrtoint ptr %str to i64103  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast104  %conv = trunc i64 %sub.ptr.sub to i32105  br label %cleanup106 107cleanup:108  %retval.0 = phi i32 [ %conv, %do.end ], [ 0, %entry ]109  ret i32 %retval.0110}111 112; int valid_strlen_with_aux_indvar(const char* str) {113;   int count = 0;114;   int count_offset = -10;115;   int count_multiple = 0;116;117;   while (*str) {118;     ++str;119;     ++count;120;     ++count_offset;121;     count_multiple += 2;122;     ++foo;123;   }124;125;   usei(count);126;   usei(count_offset);127;   usei(count_multiple);128;   use(str);129;   use(foo);130; }131define dso_local void @valid_strlen_with_aux_indvar(ptr noundef %str, ptr noundef %foo) local_unnamed_addr {132; CHECK-LABEL: define dso_local void @valid_strlen_with_aux_indvar(133; CHECK-SAME: ptr noundef [[STR:%.*]], ptr noundef [[FOO:%.*]]) local_unnamed_addr {134; CHECK-NEXT:  [[ENTRY:.*]]:135; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR]], align 1136; CHECK-NEXT:    [[TOBOOL_NOT9:%.*]] = icmp eq i8 [[TMP0]], 0137; CHECK-NEXT:    br i1 [[TOBOOL_NOT9]], label %[[WHILE_END:.*]], label %[[WHILE_BODY_PREHEADER:.*]]138; CHECK:       [[WHILE_BODY_PREHEADER]]:139; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[STR]], i64 1140; CHECK-NEXT:    [[STRLEN:%.*]] = call i64 @strlen(ptr [[SCEVGEP]])141; CHECK-NEXT:    [[TMP1:%.*]] = add i64 [[STRLEN]], 1142; CHECK-NEXT:    [[SCEVGEP1:%.*]] = getelementptr i8, ptr [[STR]], i64 [[TMP1]]143; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[STRLEN]] to i32144; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[TMP2]], 1145; CHECK-NEXT:    [[TMP4:%.*]] = trunc i64 [[STRLEN]] to i32146; CHECK-NEXT:    [[TMP5:%.*]] = add i32 [[TMP4]], -9147; CHECK-NEXT:    [[TMP6:%.*]] = trunc i64 [[STRLEN]] to i32148; CHECK-NEXT:    [[TMP7:%.*]] = shl i32 [[TMP6]], 1149; CHECK-NEXT:    [[TMP8:%.*]] = add i32 [[TMP7]], 2150; CHECK-NEXT:    [[TMP9:%.*]] = add i64 [[STRLEN]], 1151; CHECK-NEXT:    [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[FOO]], i64 [[TMP9]]152; CHECK-NEXT:    br label %[[WHILE_BODY:.*]]153; CHECK:       [[WHILE_BODY]]:154; CHECK-NEXT:    [[COUNT_MULTIPLE_014:%.*]] = phi i32 [ [[ADD:%.*]], %[[WHILE_BODY]] ], [ 0, %[[WHILE_BODY_PREHEADER]] ]155; CHECK-NEXT:    [[COUNT_OFFSET_013:%.*]] = phi i32 [ [[INC1:%.*]], %[[WHILE_BODY]] ], [ -10, %[[WHILE_BODY_PREHEADER]] ]156; CHECK-NEXT:    [[COUNT_012:%.*]] = phi i32 [ [[INC:%.*]], %[[WHILE_BODY]] ], [ 0, %[[WHILE_BODY_PREHEADER]] ]157; CHECK-NEXT:    [[FOO_ADDR_011:%.*]] = phi ptr [ [[INCDEC_PTR2:%.*]], %[[WHILE_BODY]] ], [ [[FOO]], %[[WHILE_BODY_PREHEADER]] ]158; CHECK-NEXT:    [[STR_ADDR_010:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], %[[WHILE_BODY]] ], [ [[STR]], %[[WHILE_BODY_PREHEADER]] ]159; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[STR_ADDR_010]], i64 1160; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[COUNT_012]], 1161; CHECK-NEXT:    [[INC1]] = add nsw i32 [[COUNT_OFFSET_013]], 1162; CHECK-NEXT:    [[ADD]] = add nuw nsw i32 [[COUNT_MULTIPLE_014]], 2163; CHECK-NEXT:    [[INCDEC_PTR2]] = getelementptr inbounds nuw i8, ptr [[FOO_ADDR_011]], i64 1164; CHECK-NEXT:    [[TMP10:%.*]] = load i8, ptr [[INCDEC_PTR]], align 1165; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i8 [[TMP10]], 0166; CHECK-NEXT:    br i1 true, label %[[WHILE_END_LOOPEXIT:.*]], label %[[WHILE_BODY]]167; CHECK:       [[WHILE_END_LOOPEXIT]]:168; CHECK-NEXT:    br label %[[WHILE_END]]169; CHECK:       [[WHILE_END]]:170; CHECK-NEXT:    [[STR_ADDR_0_LCSSA:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[SCEVGEP1]], %[[WHILE_END_LOOPEXIT]] ]171; CHECK-NEXT:    [[FOO_ADDR_0_LCSSA:%.*]] = phi ptr [ [[FOO]], %[[ENTRY]] ], [ [[SCEVGEP2]], %[[WHILE_END_LOOPEXIT]] ]172; CHECK-NEXT:    [[COUNT_0_LCSSA:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[TMP3]], %[[WHILE_END_LOOPEXIT]] ]173; CHECK-NEXT:    [[COUNT_OFFSET_0_LCSSA:%.*]] = phi i32 [ -10, %[[ENTRY]] ], [ [[TMP5]], %[[WHILE_END_LOOPEXIT]] ]174; CHECK-NEXT:    [[COUNT_MULTIPLE_0_LCSSA:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[TMP8]], %[[WHILE_END_LOOPEXIT]] ]175; CHECK-NEXT:    tail call void @usei(i32 noundef [[COUNT_0_LCSSA]])176; CHECK-NEXT:    tail call void @usei(i32 noundef [[COUNT_OFFSET_0_LCSSA]])177; CHECK-NEXT:    tail call void @usei(i32 noundef [[COUNT_MULTIPLE_0_LCSSA]])178; CHECK-NEXT:    tail call void @use(ptr noundef nonnull [[STR_ADDR_0_LCSSA]])179; CHECK-NEXT:    tail call void @use(ptr noundef [[FOO_ADDR_0_LCSSA]])180; CHECK-NEXT:    ret void181;182entry:183  %0 = load i8, ptr %str, align 1184  %tobool.not9 = icmp eq i8 %0, 0185  br i1 %tobool.not9, label %while.end, label %while.body186 187while.body:188  %count_multiple.014 = phi i32 [ %add, %while.body ], [ 0, %entry ]189  %count_offset.013 = phi i32 [ %inc1, %while.body ], [ -10, %entry ]190  %count.012 = phi i32 [ %inc, %while.body ], [ 0, %entry ]191  %foo.addr.011 = phi ptr [ %incdec.ptr2, %while.body ], [ %foo, %entry ]192  %str.addr.010 = phi ptr [ %incdec.ptr, %while.body ], [ %str, %entry ]193  %incdec.ptr = getelementptr inbounds nuw i8, ptr %str.addr.010, i64 1194  %inc = add nuw nsw i32 %count.012, 1195  %inc1 = add nsw i32 %count_offset.013, 1196  %add = add nuw nsw i32 %count_multiple.014, 2197  %incdec.ptr2 = getelementptr inbounds nuw i8, ptr %foo.addr.011, i64 1198  %1 = load i8, ptr %incdec.ptr, align 1199  %tobool.not = icmp eq i8 %1, 0200  br i1 %tobool.not, label %while.end, label %while.body201 202while.end:203  %str.addr.0.lcssa = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.body ]204  %foo.addr.0.lcssa = phi ptr [ %foo, %entry ], [ %incdec.ptr2, %while.body ]205  %count.0.lcssa = phi i32 [ 0, %entry ], [ %inc, %while.body ]206  %count_offset.0.lcssa = phi i32 [ -10, %entry ], [ %inc1, %while.body ]207  %count_multiple.0.lcssa = phi i32 [ 0, %entry ], [ %add, %while.body ]208  tail call void @usei(i32 noundef %count.0.lcssa) #3209  tail call void @usei(i32 noundef %count_offset.0.lcssa) #3210  tail call void @usei(i32 noundef %count_multiple.0.lcssa) #3211  tail call void @use(ptr noundef nonnull %str.addr.0.lcssa) #3212  tail call void @use(ptr noundef %foo.addr.0.lcssa) #3213  ret void214}215 216; int valid_strlen_index(const char* str) {217;     int i = 0;218;     while (str[i]) {219;         ++i;220;     }221;     return i;222; }223define i32 @valid_strlen_index(ptr %str) {224; CHECK-LABEL: define i32 @valid_strlen_index(225; CHECK-SAME: ptr [[STR:%.*]]) {226; CHECK-NEXT:  [[ENTRY:.*]]:227; CHECK-NEXT:    [[STRLEN:%.*]] = call i64 @strlen(ptr [[STR]])228; CHECK-NEXT:    br label %[[WHILE_COND:.*]]229; CHECK:       [[WHILE_COND]]:230; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], %[[WHILE_COND]] ], [ 0, %[[ENTRY]] ]231; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[STR]], i64 [[INDVARS_IV]]232; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[ARRAYIDX]], align 1233; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i8 [[TMP0]], 0234; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1235; CHECK-NEXT:    br i1 true, label %[[WHILE_END:.*]], label %[[WHILE_COND]]236; CHECK:       [[WHILE_END]]:237; CHECK-NEXT:    [[TMP1:%.*]] = trunc nuw nsw i64 [[STRLEN]] to i32238; CHECK-NEXT:    ret i32 [[TMP1]]239;240entry:241  br label %while.cond242 243while.cond:244  %indvars.iv = phi i64 [ %indvars.iv.next, %while.cond ], [ 0, %entry ]245  %arrayidx = getelementptr inbounds i8, ptr %str, i64 %indvars.iv246  %0 = load i8, ptr %arrayidx, align 1247  %tobool.not = icmp eq i8 %0, 0248  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1249  br i1 %tobool.not, label %while.end, label %while.cond250 251while.end:252  %1 = trunc nuw nsw i64 %indvars.iv to i32253  ret i32 %1254}255 256; void valid_strlen_offset(const my_char* str) {257;     if (*(str++) == '\0') return;258;     if (*(str++) == '\0') return;259;     if (*(str++) == '\0') return;260;     while (*str) {261;         ++str;262;     }263;     use(str);264; }265define dso_local void @valid_strlen_offset(ptr noundef %str) local_unnamed_addr {266; CHECK-LABEL: define dso_local void @valid_strlen_offset(267; CHECK-SAME: ptr noundef [[STR:%.*]]) local_unnamed_addr {268; CHECK-NEXT:  [[ENTRY:.*:]]269; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR]], align 1270; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i8 [[TMP0]], 0271; CHECK-NEXT:    br i1 [[CMP]], label %[[RETURN:.*]], label %[[IF_END:.*]]272; CHECK:       [[IF_END]]:273; CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[STR]], i64 1274; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[INCDEC_PTR]], align 1275; CHECK-NEXT:    [[CMP4:%.*]] = icmp eq i8 [[TMP1]], 0276; CHECK-NEXT:    br i1 [[CMP4]], label %[[RETURN]], label %[[IF_END7:.*]]277; CHECK:       [[IF_END7]]:278; CHECK-NEXT:    [[INCDEC_PTR2:%.*]] = getelementptr inbounds nuw i8, ptr [[STR]], i64 2279; CHECK-NEXT:    [[TMP2:%.*]] = load i8, ptr [[INCDEC_PTR2]], align 1280; CHECK-NEXT:    [[CMP10:%.*]] = icmp eq i8 [[TMP2]], 0281; CHECK-NEXT:    br i1 [[CMP10]], label %[[RETURN]], label %[[WHILE_COND_PREHEADER:.*]]282; CHECK:       [[WHILE_COND_PREHEADER]]:283; CHECK-NEXT:    [[INCDEC_PTR8:%.*]] = getelementptr i8, ptr [[STR]], i64 3284; CHECK-NEXT:    [[STRLEN:%.*]] = call i64 @strlen(ptr [[INCDEC_PTR8]])285; CHECK-NEXT:    [[TMP3:%.*]] = add i64 [[STRLEN]], 3286; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[STR]], i64 [[TMP3]]287; CHECK-NEXT:    br label %[[WHILE_COND:.*]]288; CHECK:       [[WHILE_COND]]:289; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[INCDEC_PTR14:%.*]], %[[WHILE_COND]] ], [ [[INCDEC_PTR8]], %[[WHILE_COND_PREHEADER]] ]290; CHECK-NEXT:    [[TMP4:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1291; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i8 [[TMP4]], 0292; CHECK-NEXT:    [[INCDEC_PTR14]] = getelementptr inbounds nuw i8, ptr [[STR_ADDR_0]], i64 1293; CHECK-NEXT:    br i1 true, label %[[WHILE_END:.*]], label %[[WHILE_COND]]294; CHECK:       [[WHILE_END]]:295; CHECK-NEXT:    tail call void @use(ptr noundef nonnull [[SCEVGEP]])296; CHECK-NEXT:    br label %[[RETURN]]297; CHECK:       [[RETURN]]:298; CHECK-NEXT:    ret void299;300entry:301  %0 = load i8, ptr %str, align 1302  %cmp = icmp eq i8 %0, 0303  br i1 %cmp, label %return, label %if.end304 305if.end:306  %incdec.ptr = getelementptr inbounds nuw i8, ptr %str, i64 1307  %1 = load i8, ptr %incdec.ptr, align 1308  %cmp4 = icmp eq i8 %1, 0309  br i1 %cmp4, label %return, label %if.end7310 311if.end7:312  %incdec.ptr2 = getelementptr inbounds nuw i8, ptr %str, i64 2313  %2 = load i8, ptr %incdec.ptr2, align 1314  %cmp10 = icmp eq i8 %2, 0315  br i1 %cmp10, label %return, label %while.cond.preheader316 317while.cond.preheader:318  %incdec.ptr8 = getelementptr inbounds nuw i8, ptr %str, i64 3319  br label %while.cond320 321while.cond:322  %str.addr.0 = phi ptr [ %incdec.ptr14, %while.cond ], [ %incdec.ptr8, %while.cond.preheader ]323  %3 = load i8, ptr %str.addr.0, align 1324  %tobool.not = icmp eq i8 %3, 0325  %incdec.ptr14 = getelementptr inbounds nuw i8, ptr %str.addr.0, i64 1326  br i1 %tobool.not, label %while.end, label %while.cond327 328while.end:329  tail call void @use(ptr noundef nonnull %str.addr.0) #3330  br label %return331 332return:333  ret void334}335 336; void valid_nested_idiom(const char** strs, int n) {337;     for (int i = 0; i < n; ++i) {338;         const char* s = strs[i];339;         int count = 0;340;         while (*s) {341;             ++s;342;             ++count;343;         }344;         usei(count);345;     }346; }347define void @valid_nested_idiom(ptr %strs, i32 %n) {348; CHECK-LABEL: define void @valid_nested_idiom(349; CHECK-SAME: ptr [[STRS:%.*]], i32 [[N:%.*]]) {350; CHECK-NEXT:  [[ENTRY:.*:]]351; CHECK-NEXT:    [[CMP9:%.*]] = icmp sgt i32 [[N]], 0352; CHECK-NEXT:    br i1 [[CMP9]], label %[[FOR_BODY_PREHEADER:.*]], label %[[FOR_COND_CLEANUP:.*]]353; CHECK:       [[FOR_BODY_PREHEADER]]:354; CHECK-NEXT:    [[WIDE_TRIP_COUNT:%.*]] = zext nneg i32 [[N]] to i64355; CHECK-NEXT:    br label %[[FOR_BODY:.*]]356; CHECK:       [[FOR_COND_CLEANUP_LOOPEXIT:.*]]:357; CHECK-NEXT:    br label %[[FOR_COND_CLEANUP]]358; CHECK:       [[FOR_COND_CLEANUP]]:359; CHECK-NEXT:    ret void360; CHECK:       [[FOR_BODY]]:361; CHECK-NEXT:    [[INDVARS_IV:%.*]] = phi i64 [ 0, %[[FOR_BODY_PREHEADER]] ], [ [[INDVARS_IV_NEXT:%.*]], %[[WHILE_END:.*]] ]362; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds ptr, ptr [[STRS]], i64 [[INDVARS_IV]]363; CHECK-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8364; CHECK-NEXT:    [[TMP1:%.*]] = load i8, ptr [[TMP0]], align 1365; CHECK-NEXT:    [[TOBOOL_NOT6:%.*]] = icmp eq i8 [[TMP1]], 0366; CHECK-NEXT:    br i1 [[TOBOOL_NOT6]], label %[[WHILE_END]], label %[[WHILE_BODY_PREHEADER:.*]]367; CHECK:       [[WHILE_BODY_PREHEADER]]:368; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[TMP0]], i64 1369; CHECK-NEXT:    [[STRLEN:%.*]] = call i64 @strlen(ptr [[SCEVGEP]])370; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[STRLEN]] to i32371; CHECK-NEXT:    [[TMP3:%.*]] = add i32 [[TMP2]], 1372; CHECK-NEXT:    br label %[[WHILE_BODY:.*]]373; CHECK:       [[WHILE_BODY]]:374; CHECK-NEXT:    [[COUNT_08:%.*]] = phi i32 [ [[INC:%.*]], %[[WHILE_BODY]] ], [ 0, %[[WHILE_BODY_PREHEADER]] ]375; CHECK-NEXT:    [[S_07:%.*]] = phi ptr [ [[INCDEC_PTR:%.*]], %[[WHILE_BODY]] ], [ [[TMP0]], %[[WHILE_BODY_PREHEADER]] ]376; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr inbounds nuw i8, ptr [[S_07]], i64 1377; CHECK-NEXT:    [[INC]] = add nuw nsw i32 [[COUNT_08]], 1378; CHECK-NEXT:    [[TMP4:%.*]] = load i8, ptr [[INCDEC_PTR]], align 1379; CHECK-NEXT:    [[TOBOOL_NOT:%.*]] = icmp eq i8 [[TMP4]], 0380; CHECK-NEXT:    br i1 true, label %[[WHILE_END_LOOPEXIT:.*]], label %[[WHILE_BODY]]381; CHECK:       [[WHILE_END_LOOPEXIT]]:382; CHECK-NEXT:    br label %[[WHILE_END]]383; CHECK:       [[WHILE_END]]:384; CHECK-NEXT:    [[COUNT_0_LCSSA:%.*]] = phi i32 [ 0, %[[FOR_BODY]] ], [ [[TMP3]], %[[WHILE_END_LOOPEXIT]] ]385; CHECK-NEXT:    tail call void @usei(i32 [[COUNT_0_LCSSA]])386; CHECK-NEXT:    [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1387; CHECK-NEXT:    [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]]388; CHECK-NEXT:    br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP_LOOPEXIT]], label %[[FOR_BODY]]389;390entry:391  %cmp9 = icmp sgt i32 %n, 0392  br i1 %cmp9, label %for.body.preheader, label %for.cond.cleanup393 394for.body.preheader:395  %wide.trip.count = zext nneg i32 %n to i64396  br label %for.body397 398for.cond.cleanup:399  ret void400 401for.body:402  %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %while.end ]403  %arrayidx = getelementptr inbounds ptr, ptr %strs, i64 %indvars.iv404  %0 = load ptr, ptr %arrayidx, align 8405  %1 = load i8, ptr %0, align 1406  %tobool.not6 = icmp eq i8 %1, 0407  br i1 %tobool.not6, label %while.end, label %while.body408 409while.body:410  %count.08 = phi i32 [ %inc, %while.body ], [ 0, %for.body ]411  %s.07 = phi ptr [ %incdec.ptr, %while.body ], [ %0, %for.body ]412  %incdec.ptr = getelementptr inbounds nuw i8, ptr %s.07, i64 1413  %inc = add nuw nsw i32 %count.08, 1414  %2 = load i8, ptr %incdec.ptr, align 1415  %tobool.not = icmp eq i8 %2, 0416  br i1 %tobool.not, label %while.end, label %while.body417 418while.end:419  %count.0.lcssa = phi i32 [ 0, %for.body ], [ %inc, %while.body ]420  tail call void @usei(i32 %count.0.lcssa) #2421  %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1422  %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count423  br i1 %exitcond.not, label %for.cond.cleanup, label %for.body424}425 426define i64 @invalid_strlen_has_side_effects(ptr %str) {427; CHECK-LABEL: define i64 @invalid_strlen_has_side_effects(428; CHECK-SAME: ptr [[STR:%.*]]) {429; CHECK-NEXT:  [[ENTRY:.*]]:430; CHECK-NEXT:    br label %[[WHILE_COND:.*]]431; CHECK:       [[WHILE_COND]]:432; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]433; CHECK-NEXT:    [[TMP0:%.*]] = load volatile i8, ptr [[STR_ADDR_0]], align 1434; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0435; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1436; CHECK-NEXT:    br i1 [[CMP_NOT]], label %[[WHILE_END:.*]], label %[[WHILE_COND]]437; CHECK:       [[WHILE_END]]:438; CHECK-NEXT:    [[STR_ADDR_0_LCSSA:%.*]] = phi ptr [ [[STR_ADDR_0]], %[[WHILE_COND]] ]439; CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[STR_ADDR_0_LCSSA]] to i64440; CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64441; CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]442; CHECK-NEXT:    ret i64 [[SUB_PTR_SUB]]443;444entry:445  br label %while.cond446 447while.cond:448  %str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]449  %0 = load volatile i8, ptr %str.addr.0, align 1450  %cmp.not = icmp eq i8 %0, 0451  %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 1452  br i1 %cmp.not, label %while.end, label %while.cond453 454while.end:455  %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64456  %sub.ptr.rhs.cast = ptrtoint ptr %str to i64457  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast458  ret i64 %sub.ptr.sub459}460 461 462define i8 @invalid_exit_phi_scev(ptr %str) {463; CHECK-LABEL: define i8 @invalid_exit_phi_scev(464; CHECK-SAME: ptr [[STR:%.*]]) {465; CHECK-NEXT:  [[ENTRY:.*]]:466; CHECK-NEXT:    br label %[[WHILE_COND:.*]]467; CHECK:       [[WHILE_COND]]:468; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]469; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1470; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0471; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1472; CHECK-NEXT:    br i1 [[CMP_NOT]], label %[[WHILE_END:.*]], label %[[WHILE_COND]]473; CHECK:       [[WHILE_END]]:474; CHECK-NEXT:    [[STR_ADDR_0_LCSSA:%.*]] = phi ptr [ [[STR_ADDR_0]], %[[WHILE_COND]] ]475; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi i8 [ [[TMP0]], %[[WHILE_COND]] ]476; CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[STR_ADDR_0_LCSSA]] to i64477; CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64478; CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]479; CHECK-NEXT:    ret i8 [[DOTLCSSA]]480;481entry:482  br label %while.cond483 484while.cond:485  %str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]486  %0 = load i8, ptr %str.addr.0, align 1487  %cmp.not = icmp eq i8 %0, 0488  %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 1489  br i1 %cmp.not, label %while.end, label %while.cond490 491while.end:492  %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64493  %sub.ptr.rhs.cast = ptrtoint ptr %str to i64494  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast495 496  ; %0.lcssa has invalid scev rec {%0} expected to be {%str,+,constant}497  ret i8 %0498}499 500 501 502define i64 @invalid_branch_cond(ptr %str) {503; CHECK-LABEL: define i64 @invalid_branch_cond(504; CHECK-SAME: ptr [[STR:%.*]]) {505; CHECK-NEXT:  [[ENTRY:.*]]:506; CHECK-NEXT:    br label %[[WHILE_COND:.*]]507; CHECK:       [[WHILE_COND]]:508; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]509; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1510; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 10511; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1512; CHECK-NEXT:    br i1 [[CMP_NOT]], label %[[WHILE_END:.*]], label %[[WHILE_COND]]513; CHECK:       [[WHILE_END]]:514; CHECK-NEXT:    [[STR_ADDR_0_LCSSA:%.*]] = phi ptr [ [[STR_ADDR_0]], %[[WHILE_COND]] ]515; CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[STR_ADDR_0_LCSSA]] to i64516; CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64517; CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]518; CHECK-NEXT:    ret i64 [[SUB_PTR_SUB]]519;520entry:521  br label %while.cond522 523while.cond:524  %str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]525  %0 = load i8, ptr %str.addr.0, align 1526 527  ; We compare against '\n' instead of '\0'528  %cmp.not = icmp eq i8 %0, 10529 530  %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 1531  br i1 %cmp.not, label %while.end, label %while.cond532 533while.end:534  %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64535  %sub.ptr.rhs.cast = ptrtoint ptr %str to i64536  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast537  ret i64 %sub.ptr.sub538}539 540define i64 @invalid_unknown_step_size(ptr %str, i64 %step) {541; CHECK-LABEL: define i64 @invalid_unknown_step_size(542; CHECK-SAME: ptr [[STR:%.*]], i64 [[STEP:%.*]]) {543; CHECK-NEXT:  [[ENTRY:.*]]:544; CHECK-NEXT:    br label %[[WHILE_COND:.*]]545; CHECK:       [[WHILE_COND]]:546; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]547; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1548; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0549; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 [[STEP]]550; CHECK-NEXT:    br i1 [[CMP_NOT]], label %[[WHILE_END:.*]], label %[[WHILE_COND]]551; CHECK:       [[WHILE_END]]:552; CHECK-NEXT:    [[STR_ADDR_0_LCSSA:%.*]] = phi ptr [ [[STR_ADDR_0]], %[[WHILE_COND]] ]553; CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[STR_ADDR_0_LCSSA]] to i64554; CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64555; CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]556; CHECK-NEXT:    ret i64 [[SUB_PTR_SUB]]557;558entry:559  br label %while.cond560 561while.cond:562  %str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]563  %0 = load i8, ptr %str.addr.0, align 1564  %cmp.not = icmp eq i8 %0, 0565  %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 %step566  br i1 %cmp.not, label %while.end, label %while.cond567 568while.end:569  %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64570  %sub.ptr.rhs.cast = ptrtoint ptr %str to i64571  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast572  ret i64 %sub.ptr.sub573}574 575declare ptr @pure(ptr) #0;576attributes #0 = { mustprogress nofree norecurse nosync nounwind willreturn memory(none) }577 578define i64 @invalid_add_rec(ptr %str) {579; CHECK-LABEL: define i64 @invalid_add_rec(580; CHECK-SAME: ptr [[STR:%.*]]) {581; CHECK-NEXT:  [[ENTRY:.*]]:582; CHECK-NEXT:    br label %[[WHILE_COND:.*]]583; CHECK:       [[WHILE_COND]]:584; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]585; CHECK-NEXT:    [[INDIRECT:%.*]] = tail call ptr @pure(ptr [[STR_ADDR_0]])586; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[INDIRECT]], align 1587; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0588; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1589; CHECK-NEXT:    br i1 [[CMP_NOT]], label %[[WHILE_END:.*]], label %[[WHILE_COND]]590; CHECK:       [[WHILE_END]]:591; CHECK-NEXT:    [[STR_ADDR_0_LCSSA:%.*]] = phi ptr [ [[STR_ADDR_0]], %[[WHILE_COND]] ]592; CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[STR_ADDR_0_LCSSA]] to i64593; CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64594; CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]]595; CHECK-NEXT:    ret i64 [[SUB_PTR_SUB]]596;597entry:598  br label %while.cond599 600while.cond:601  %str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]602  %indirect = tail call ptr @pure(ptr %str.addr.0)603  %0 = load i8, ptr %indirect, align 1604  %cmp.not = icmp eq i8 %0, 0605  %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 1606  br i1 %cmp.not, label %while.end, label %while.cond607 608while.end:609  %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64610  %sub.ptr.rhs.cast = ptrtoint ptr %str to i64611  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast612  ret i64 %sub.ptr.sub613}614 615define i64 @valid_basic_strlen_with_dbg(ptr %str) {616; Make sure that the call to strlen has debug info attached.617; CHECK-LABEL: define i64 @valid_basic_strlen_with_dbg(618; CHECK-SAME: ptr [[STR:%.*]]) {619; CHECK-NEXT:  [[ENTRY:.*]]:620; CHECK-NEXT:    [[STRLEN:%.*]] = call i64 @strlen(ptr [[STR]]), !dbg [[DBGLOC1:![0-9]+]]621; CHECK-NEXT:    [[SCEVGEP:%.*]] = getelementptr i8, ptr [[STR]], i64 [[STRLEN]]622; CHECK-NEXT:    br label %[[WHILE_COND:.*]]623; CHECK:       [[WHILE_COND]]:624; CHECK-NEXT:    [[STR_ADDR_0:%.*]] = phi ptr [ [[STR]], %[[ENTRY]] ], [ [[INCDEC_PTR:%.*]], %[[WHILE_COND]] ]625; CHECK-NEXT:    [[TMP0:%.*]] = load i8, ptr [[STR_ADDR_0]], align 1, !dbg [[DBGLOC2:![0-9]+]]626; CHECK-NEXT:    [[CMP_NOT:%.*]] = icmp eq i8 [[TMP0]], 0, !dbg [[DBGLOC2]]627; CHECK-NEXT:    [[INCDEC_PTR]] = getelementptr i8, ptr [[STR_ADDR_0]], i64 1, !dbg [[DBGLOC2]]628; CHECK-NEXT:    br i1 true, label %[[WHILE_END:.*]], label %[[WHILE_COND]], !dbg [[DBGLOC1]]629; CHECK:       [[WHILE_END]]:630; CHECK-NEXT:    [[SUB_PTR_LHS_CAST:%.*]] = ptrtoint ptr [[SCEVGEP]] to i64, !dbg [[DBGLOC2]]631; CHECK-NEXT:    [[SUB_PTR_RHS_CAST:%.*]] = ptrtoint ptr [[STR]] to i64, !dbg [[DBGLOC2]]632; CHECK-NEXT:    [[SUB_PTR_SUB:%.*]] = sub i64 [[SUB_PTR_LHS_CAST]], [[SUB_PTR_RHS_CAST]], !dbg [[DBGLOC2]]633; CHECK-NEXT:    ret i64 [[SUB_PTR_SUB]], !dbg [[DBGLOC2]]634;635; CHECK: [[DBGLOC1]] = !DILocation(line: 3, column: 3636; CHECK: [[DBGLOC2]] = !DILocation(line: 5, column: 3637;638entry:639  br label %while.cond640 641while.cond:642  %str.addr.0 = phi ptr [ %str, %entry ], [ %incdec.ptr, %while.cond ]643  %0 = load i8, ptr %str.addr.0, align 1, !dbg !8644  %cmp.not = icmp eq i8 %0, 0, !dbg !8645  %incdec.ptr = getelementptr i8, ptr %str.addr.0, i64 1, !dbg !8646  br i1 %cmp.not, label %while.end, label %while.cond, !dbg !4647 648while.end:649  %sub.ptr.lhs.cast = ptrtoint ptr %str.addr.0 to i64, !dbg !8650  %sub.ptr.rhs.cast = ptrtoint ptr %str to i64, !dbg !8651  %sub.ptr.sub = sub i64 %sub.ptr.lhs.cast, %sub.ptr.rhs.cast, !dbg !8652  ret i64 %sub.ptr.sub, !dbg !8653}654 655!llvm.module.flags = !{!0}656!llvm.dbg.cu = !{!1}657 658!0 = !{i32 1, !"Debug Info Version", i32 3}659!1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang version 2.9 (trunk 127165:127174)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, retainedTypes: !3)660!2 = !DIFile(filename: "strlen.c", directory: "/tmp")661!3 = !{}662!4 = !DILocation(line: 3, column: 3, scope: !5)663!5 = distinct !DILexicalBlock(scope: !6, file: !2, line: 2, column: 21)664!6 = distinct !DISubprogram(name: "foo", scope: !2, file: !2, line: 2, type: !7, virtualIndex: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !1)665!7 = !DISubroutineType(types: !3)666!8 = !DILocation(line: 5, column: 3, scope: !5)667