1cee313d2SEric Christopher; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2*e11354c0SNikita Popov; RUN: opt -S -loop-rotate < %s -verify-loop-info -verify-dom-info -verify-memoryssa | FileCheck %s 3cee313d2SEric Christopher 4cee313d2SEric Christophertarget datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 5cee313d2SEric Christophertarget triple = "thumbv8m.base-arm-none-eabi" 6cee313d2SEric Christopher 7cee313d2SEric Christopher%struct.List = type { %struct.List*, i32 } 8cee313d2SEric Christopher 9cee313d2SEric Christopherdefine void @list_add(%struct.List** nocapture %list, %struct.List* %data) { 10cee313d2SEric Christopher; CHECK-LABEL: @list_add( 11cee313d2SEric Christopher; CHECK-NEXT: entry: 12cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = load %struct.List*, %struct.List** [[LIST:%.*]], align 4 13cee313d2SEric Christopher; CHECK-NEXT: [[VAL2:%.*]] = getelementptr inbounds [[STRUCT_LIST:%.*]], %struct.List* [[TMP0]], i32 0, i32 1 14cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[VAL2]], align 4 15cee313d2SEric Christopher; CHECK-NEXT: [[VAL1:%.*]] = getelementptr inbounds [[STRUCT_LIST]], %struct.List* [[DATA:%.*]], i32 0, i32 1 16cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = load i32, i32* [[VAL1]], align 4 17cee313d2SEric Christopher; CHECK-NEXT: [[CMP3:%.*]] = icmp slt i32 [[TMP1]], [[TMP2]] 18cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CMP3]], label [[IF_THEN_LR_PH:%.*]], label [[IF_ELSE6:%.*]] 19cee313d2SEric Christopher; CHECK: if.then.lr.ph: 20cee313d2SEric Christopher; CHECK-NEXT: br label [[IF_THEN:%.*]] 21cee313d2SEric Christopher; CHECK: for.cond: 22cee313d2SEric Christopher; CHECK-NEXT: [[CURR_0:%.*]] = phi %struct.List* [ [[TMP5:%.*]], [[IF_THEN]] ] 23cee313d2SEric Christopher; CHECK-NEXT: [[PREV_0:%.*]] = phi %struct.List* [ [[CURR_04:%.*]], [[IF_THEN]] ] 24cee313d2SEric Christopher; CHECK-NEXT: [[VAL:%.*]] = getelementptr inbounds [[STRUCT_LIST]], %struct.List* [[CURR_0]], i32 0, i32 1 25cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[VAL]], align 4 26cee313d2SEric Christopher; CHECK-NEXT: [[TMP4:%.*]] = load i32, i32* [[VAL1]], align 4 27cee313d2SEric Christopher; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[TMP3]], [[TMP4]] 28cee313d2SEric Christopher; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN]], label [[FOR_COND_IF_ELSE6_CRIT_EDGE:%.*]] 29cee313d2SEric Christopher; CHECK: if.then: 30cee313d2SEric Christopher; CHECK-NEXT: [[CURR_04]] = phi %struct.List* [ [[TMP0]], [[IF_THEN_LR_PH]] ], [ [[CURR_0]], [[FOR_COND:%.*]] ] 31cee313d2SEric Christopher; CHECK-NEXT: [[NEXT:%.*]] = getelementptr inbounds [[STRUCT_LIST]], %struct.List* [[CURR_04]], i32 0, i32 0 32cee313d2SEric Christopher; CHECK-NEXT: [[TMP5]] = load %struct.List*, %struct.List** [[NEXT]], align 4 33cee313d2SEric Christopher; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq %struct.List* [[TMP5]], null 34cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_ELSE:%.*]], label [[FOR_COND]] 35cee313d2SEric Christopher; CHECK: if.else: 36cee313d2SEric Christopher; CHECK-NEXT: [[NEXT_LCSSA:%.*]] = phi %struct.List** [ [[NEXT]], [[IF_THEN]] ] 37cee313d2SEric Christopher; CHECK-NEXT: store %struct.List* [[DATA]], %struct.List** [[NEXT_LCSSA]], align 4 38cee313d2SEric Christopher; CHECK-NEXT: [[NEXT5:%.*]] = getelementptr inbounds [[STRUCT_LIST]], %struct.List* [[DATA]], i32 0, i32 0 39cee313d2SEric Christopher; CHECK-NEXT: store %struct.List* null, %struct.List** [[NEXT5]], align 4 40cee313d2SEric Christopher; CHECK-NEXT: br label [[FOR_END:%.*]] 41cee313d2SEric Christopher; CHECK: for.cond.if.else6_crit_edge: 42cee313d2SEric Christopher; CHECK-NEXT: [[SPLIT:%.*]] = phi %struct.List* [ [[PREV_0]], [[FOR_COND]] ] 43cee313d2SEric Christopher; CHECK-NEXT: br label [[IF_ELSE6]] 44cee313d2SEric Christopher; CHECK: if.else6: 45cee313d2SEric Christopher; CHECK-NEXT: [[PREV_0_LCSSA:%.*]] = phi %struct.List* [ [[SPLIT]], [[FOR_COND_IF_ELSE6_CRIT_EDGE]] ], [ null, [[ENTRY:%.*]] ] 46cee313d2SEric Christopher; CHECK-NEXT: [[TOBOOL7:%.*]] = icmp eq %struct.List* [[PREV_0_LCSSA]], null 47cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TOBOOL7]], label [[IF_ELSE12:%.*]], label [[IF_THEN8:%.*]] 48cee313d2SEric Christopher; CHECK: if.then8: 49cee313d2SEric Christopher; CHECK-NEXT: [[NEXT9:%.*]] = getelementptr inbounds [[STRUCT_LIST]], %struct.List* [[PREV_0_LCSSA]], i32 0, i32 0 50cee313d2SEric Christopher; CHECK-NEXT: [[TMP6:%.*]] = bitcast %struct.List* [[PREV_0_LCSSA]] to i32* 51cee313d2SEric Christopher; CHECK-NEXT: [[TMP7:%.*]] = load i32, i32* [[TMP6]], align 4 52cee313d2SEric Christopher; CHECK-NEXT: [[TMP8:%.*]] = bitcast %struct.List* [[DATA]] to i32* 53cee313d2SEric Christopher; CHECK-NEXT: store i32 [[TMP7]], i32* [[TMP8]], align 4 54cee313d2SEric Christopher; CHECK-NEXT: store %struct.List* [[DATA]], %struct.List** [[NEXT9]], align 4 55cee313d2SEric Christopher; CHECK-NEXT: br label [[FOR_END]] 56cee313d2SEric Christopher; CHECK: if.else12: 57cee313d2SEric Christopher; CHECK-NEXT: [[TMP9:%.*]] = bitcast %struct.List** [[LIST]] to i32* 58cee313d2SEric Christopher; CHECK-NEXT: [[TMP10:%.*]] = load i32, i32* [[TMP9]], align 4 59cee313d2SEric Christopher; CHECK-NEXT: [[TMP11:%.*]] = bitcast %struct.List* [[DATA]] to i32* 60cee313d2SEric Christopher; CHECK-NEXT: store i32 [[TMP10]], i32* [[TMP11]], align 4 61cee313d2SEric Christopher; CHECK-NEXT: store %struct.List* [[DATA]], %struct.List** [[LIST]], align 4 62cee313d2SEric Christopher; CHECK-NEXT: br label [[FOR_END]] 63cee313d2SEric Christopher; CHECK: for.end: 64cee313d2SEric Christopher; CHECK-NEXT: ret void 65cee313d2SEric Christopher; 66cee313d2SEric Christopherentry: 67cee313d2SEric Christopher %0 = load %struct.List*, %struct.List** %list, align 4 68cee313d2SEric Christopher br label %for.cond 69cee313d2SEric Christopher 70cee313d2SEric Christopherfor.cond: ; preds = %if.then, %entry 71cee313d2SEric Christopher %curr.0 = phi %struct.List* [ %0, %entry ], [ %3, %if.then ] 72cee313d2SEric Christopher %prev.0 = phi %struct.List* [ null, %entry ], [ %curr.0, %if.then ] 73cee313d2SEric Christopher %val = getelementptr inbounds %struct.List, %struct.List* %curr.0, i32 0, i32 1 74cee313d2SEric Christopher %1 = load i32, i32* %val, align 4 75cee313d2SEric Christopher %val1 = getelementptr inbounds %struct.List, %struct.List* %data, i32 0, i32 1 76cee313d2SEric Christopher %2 = load i32, i32* %val1, align 4 77cee313d2SEric Christopher %cmp = icmp slt i32 %1, %2 78cee313d2SEric Christopher br i1 %cmp, label %if.then, label %if.else6 79cee313d2SEric Christopher 80cee313d2SEric Christopherif.then: ; preds = %for.cond 81cee313d2SEric Christopher %next = getelementptr inbounds %struct.List, %struct.List* %curr.0, i32 0, i32 0 82cee313d2SEric Christopher %3 = load %struct.List*, %struct.List** %next, align 4 83cee313d2SEric Christopher %tobool = icmp eq %struct.List* %3, null 84cee313d2SEric Christopher br i1 %tobool, label %if.else, label %for.cond 85cee313d2SEric Christopher 86cee313d2SEric Christopherif.else: ; preds = %if.then 87cee313d2SEric Christopher %next.lcssa = phi %struct.List** [ %next, %if.then ] 88cee313d2SEric Christopher store %struct.List* %data, %struct.List** %next.lcssa, align 4 89cee313d2SEric Christopher %next5 = getelementptr inbounds %struct.List, %struct.List* %data, i32 0, i32 0 90cee313d2SEric Christopher store %struct.List* null, %struct.List** %next5, align 4 91cee313d2SEric Christopher br label %for.end 92cee313d2SEric Christopher 93cee313d2SEric Christopherif.else6: ; preds = %for.cond 94cee313d2SEric Christopher %prev.0.lcssa = phi %struct.List* [ %prev.0, %for.cond ] 95cee313d2SEric Christopher %tobool7 = icmp eq %struct.List* %prev.0.lcssa, null 96cee313d2SEric Christopher br i1 %tobool7, label %if.else12, label %if.then8 97cee313d2SEric Christopher 98cee313d2SEric Christopherif.then8: ; preds = %if.else6 99cee313d2SEric Christopher %next9 = getelementptr inbounds %struct.List, %struct.List* %prev.0.lcssa, i32 0, i32 0 100cee313d2SEric Christopher %4 = bitcast %struct.List* %prev.0.lcssa to i32* 101cee313d2SEric Christopher %5 = load i32, i32* %4, align 4 102cee313d2SEric Christopher %6 = bitcast %struct.List* %data to i32* 103cee313d2SEric Christopher store i32 %5, i32* %6, align 4 104cee313d2SEric Christopher store %struct.List* %data, %struct.List** %next9, align 4 105cee313d2SEric Christopher br label %for.end 106cee313d2SEric Christopher 107cee313d2SEric Christopherif.else12: ; preds = %if.else6 108cee313d2SEric Christopher %7 = bitcast %struct.List** %list to i32* 109cee313d2SEric Christopher %8 = load i32, i32* %7, align 4 110cee313d2SEric Christopher %9 = bitcast %struct.List* %data to i32* 111cee313d2SEric Christopher store i32 %8, i32* %9, align 4 112cee313d2SEric Christopher store %struct.List* %data, %struct.List** %list, align 4 113cee313d2SEric Christopher br label %for.end 114cee313d2SEric Christopher 115cee313d2SEric Christopherfor.end: ; preds = %if.else12, %if.then8, %if.else 116cee313d2SEric Christopher ret void 117cee313d2SEric Christopher} 118cee313d2SEric Christopher 119cee313d2SEric Christopherdefine i32 @test2(i32* %l) { 120cee313d2SEric Christopher; CHECK-LABEL: @test2( 121cee313d2SEric Christopher; CHECK-NEXT: entry: 122cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[L:%.*]], align 4 123cee313d2SEric Christopher; CHECK-NEXT: [[TOBOOL2:%.*]] = icmp eq i32 [[TMP0]], 0 124cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TOBOOL2]], label [[CLEANUP:%.*]], label [[DO_COND_LR_PH:%.*]] 125cee313d2SEric Christopher; CHECK: do.cond.lr.ph: 126cee313d2SEric Christopher; CHECK-NEXT: br label [[DO_COND:%.*]] 127cee313d2SEric Christopher; CHECK: do.body: 128cee313d2SEric Christopher; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ [[REM:%.*]], [[DO_COND]] ] 129cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[L]], align 4 130cee313d2SEric Christopher; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP1]], 0 131cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TOBOOL]], label [[DO_BODY_CLEANUP_CRIT_EDGE:%.*]], label [[DO_COND]] 132cee313d2SEric Christopher; CHECK: do.body.cleanup_crit_edge: 133cee313d2SEric Christopher; CHECK-NEXT: [[SPLIT:%.*]] = phi i32 [ [[A_0]], [[DO_BODY:%.*]] ] 134cee313d2SEric Christopher; CHECK-NEXT: br label [[CLEANUP]] 135cee313d2SEric Christopher; CHECK: cleanup: 136cee313d2SEric Christopher; CHECK-NEXT: [[A_0_LCSSA:%.*]] = phi i32 [ [[SPLIT]], [[DO_BODY_CLEANUP_CRIT_EDGE]] ], [ 100, [[ENTRY:%.*]] ] 137cee313d2SEric Christopher; CHECK-NEXT: store i32 10, i32* [[L]], align 4 138cee313d2SEric Christopher; CHECK-NEXT: br label [[CLEANUP2:%.*]] 139cee313d2SEric Christopher; CHECK: do.cond: 140cee313d2SEric Christopher; CHECK-NEXT: [[TMP2:%.*]] = phi i32 [ [[TMP0]], [[DO_COND_LR_PH]] ], [ [[TMP1]], [[DO_BODY]] ] 141cee313d2SEric Christopher; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[TMP2]], 13 142cee313d2SEric Christopher; CHECK-NEXT: [[REM]] = srem i32 [[MUL]], 27 143cee313d2SEric Christopher; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[L]], align 4 144cee313d2SEric Christopher; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[TMP3]], 0 145cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TOBOOL1]], label [[CLEANUP2_LOOPEXIT:%.*]], label [[DO_BODY]] 146cee313d2SEric Christopher; CHECK: cleanup2.loopexit: 147cee313d2SEric Christopher; CHECK-NEXT: br label [[CLEANUP2]] 148cee313d2SEric Christopher; CHECK: cleanup2: 149cee313d2SEric Christopher; CHECK-NEXT: [[RETVAL_2:%.*]] = phi i32 [ [[A_0_LCSSA]], [[CLEANUP]] ], [ 0, [[CLEANUP2_LOOPEXIT]] ] 150cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RETVAL_2]] 151cee313d2SEric Christopher; 152cee313d2SEric Christopherentry: 153cee313d2SEric Christopher br label %do.body 154cee313d2SEric Christopher 155cee313d2SEric Christopherdo.body: ; preds = %do.cond, %entry 156cee313d2SEric Christopher %a.0 = phi i32 [ 100, %entry ], [ %rem, %do.cond ] 157cee313d2SEric Christopher %0 = load i32, i32* %l, align 4 158cee313d2SEric Christopher %tobool = icmp eq i32 %0, 0 159cee313d2SEric Christopher br i1 %tobool, label %cleanup, label %do.cond 160cee313d2SEric Christopher 161cee313d2SEric Christophercleanup: ; preds = %do.body 162cee313d2SEric Christopher %a.0.lcssa = phi i32 [ %a.0, %do.body ] 163cee313d2SEric Christopher store i32 10, i32* %l, align 4 164cee313d2SEric Christopher br label %cleanup2 165cee313d2SEric Christopher 166cee313d2SEric Christopherdo.cond: ; preds = %do.body 167cee313d2SEric Christopher %mul = mul nsw i32 %0, 13 168cee313d2SEric Christopher %rem = srem i32 %mul, 27 169cee313d2SEric Christopher %1 = load i32, i32* %l, align 4 170cee313d2SEric Christopher %tobool1 = icmp eq i32 %1, 0 171cee313d2SEric Christopher br i1 %tobool1, label %cleanup2.loopexit, label %do.body 172cee313d2SEric Christopher 173cee313d2SEric Christophercleanup2.loopexit: ; preds = %do.cond 174cee313d2SEric Christopher br label %cleanup2 175cee313d2SEric Christopher 176cee313d2SEric Christophercleanup2: ; preds = %cleanup2.loopexit, %cleanup 177cee313d2SEric Christopher %retval.2 = phi i32 [ %a.0.lcssa, %cleanup ], [ 0, %cleanup2.loopexit ] 178cee313d2SEric Christopher ret i32 %retval.2 179cee313d2SEric Christopher} 180cee313d2SEric Christopher 181cee313d2SEric Christopherdefine i32 @no_rotate(i32* %l) { 182cee313d2SEric Christopher; CHECK-LABEL: @no_rotate( 183cee313d2SEric Christopher; CHECK-NEXT: entry: 184cee313d2SEric Christopher; CHECK-NEXT: br label [[DO_BODY:%.*]] 185cee313d2SEric Christopher; CHECK: do.body: 186cee313d2SEric Christopher; CHECK-NEXT: [[A_0:%.*]] = phi i32 [ 100, [[ENTRY:%.*]] ], [ [[REM:%.*]], [[DO_COND:%.*]] ] 187cee313d2SEric Christopher; CHECK-NEXT: [[TMP0:%.*]] = load i32, i32* [[L:%.*]], align 4 188cee313d2SEric Christopher; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[TMP0]], 0 189cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TOBOOL]], label [[CLEANUP:%.*]], label [[DO_COND]] 190cee313d2SEric Christopher; CHECK: cleanup: 191cee313d2SEric Christopher; CHECK-NEXT: [[A_0_LCSSA:%.*]] = phi i32 [ [[A_0]], [[DO_BODY]] ] 192cee313d2SEric Christopher; CHECK-NEXT: store i32 10, i32* [[L]], align 4 193cee313d2SEric Christopher; CHECK-NEXT: br label [[CLEANUP2:%.*]] 194cee313d2SEric Christopher; CHECK: do.cond: 195cee313d2SEric Christopher; CHECK-NEXT: [[MUL:%.*]] = mul nsw i32 [[A_0]], 13 196cee313d2SEric Christopher; CHECK-NEXT: [[REM]] = srem i32 [[MUL]], 27 197cee313d2SEric Christopher; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[L]], align 4 198cee313d2SEric Christopher; CHECK-NEXT: [[TOBOOL1:%.*]] = icmp eq i32 [[TMP1]], 0 199cee313d2SEric Christopher; CHECK-NEXT: br i1 [[TOBOOL1]], label [[CLEANUP2_LOOPEXIT:%.*]], label [[DO_BODY]] 200cee313d2SEric Christopher; CHECK: cleanup2.loopexit: 201cee313d2SEric Christopher; CHECK-NEXT: br label [[CLEANUP2]] 202cee313d2SEric Christopher; CHECK: cleanup2: 203cee313d2SEric Christopher; CHECK-NEXT: [[RETVAL_2:%.*]] = phi i32 [ [[A_0_LCSSA]], [[CLEANUP]] ], [ 0, [[CLEANUP2_LOOPEXIT]] ] 204cee313d2SEric Christopher; CHECK-NEXT: ret i32 [[RETVAL_2]] 205cee313d2SEric Christopher; 206cee313d2SEric Christopherentry: 207cee313d2SEric Christopher br label %do.body 208cee313d2SEric Christopher 209cee313d2SEric Christopherdo.body: ; preds = %do.cond, %entry 210cee313d2SEric Christopher %a.0 = phi i32 [ 100, %entry ], [ %rem, %do.cond ] 211cee313d2SEric Christopher %0 = load i32, i32* %l, align 4 212cee313d2SEric Christopher %tobool = icmp eq i32 %0, 0 213cee313d2SEric Christopher br i1 %tobool, label %cleanup, label %do.cond 214cee313d2SEric Christopher 215cee313d2SEric Christophercleanup: ; preds = %do.body 216cee313d2SEric Christopher %a.0.lcssa = phi i32 [ %a.0, %do.body ] 217cee313d2SEric Christopher store i32 10, i32* %l, align 4 218cee313d2SEric Christopher br label %cleanup2 219cee313d2SEric Christopher 220cee313d2SEric Christopherdo.cond: ; preds = %do.body 221cee313d2SEric Christopher %mul = mul nsw i32 %a.0, 13 222cee313d2SEric Christopher %rem = srem i32 %mul, 27 223cee313d2SEric Christopher %1 = load i32, i32* %l, align 4 224cee313d2SEric Christopher %tobool1 = icmp eq i32 %1, 0 225cee313d2SEric Christopher br i1 %tobool1, label %cleanup2.loopexit, label %do.body 226cee313d2SEric Christopher 227cee313d2SEric Christophercleanup2.loopexit: ; preds = %do.cond 228cee313d2SEric Christopher br label %cleanup2 229cee313d2SEric Christopher 230cee313d2SEric Christophercleanup2: ; preds = %cleanup2.loopexit, %cleanup 231cee313d2SEric Christopher %retval.2 = phi i32 [ %a.0.lcssa, %cleanup ], [ 0, %cleanup2.loopexit ] 232cee313d2SEric Christopher ret i32 %retval.2 233cee313d2SEric Christopher} 234cee313d2SEric Christopher 235