1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -S -passes=loop-unroll -unroll-threshold=1 | FileCheck %s 3; RUN: opt < %s -S -passes='require<opt-remark-emit>,loop(loop-unroll-full)' -unroll-threshold=1 | FileCheck %s 4 5target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 6 7; Body fully unrolls into a single instruction after unroll and simplify 8define i32 @test(i8 %a) { 9; CHECK-LABEL: @test( 10; CHECK-NEXT: entry: 11; CHECK-NEXT: br label [[FOR_BODY:%.*]] 12; CHECK: for.body: 13; CHECK-NEXT: [[ZEXT_9:%.*]] = zext i8 [[A:%.*]] to i32 14; CHECK-NEXT: ret i32 [[ZEXT_9]] 15; 16entry: 17 br label %for.body 18 19for.body: 20 %phi = phi i64 [ 0, %entry ], [ %inc, %for.body ] 21 %zext = zext i8 %a to i32 22 %inc = add nuw nsw i64 %phi, 1 23 %cmp = icmp ult i64 %inc, 10 24 br i1 %cmp, label %for.body, label %for.exit 25 26for.exit: 27 ret i32 %zext 28} 29 30; Generalized version of previous to show benefit of using SCEV's ability 31; to prove invariance not Loop::isLoopInvaraint. 32define i32 @test2(i8 %a) { 33; CHECK-LABEL: @test2( 34; CHECK-NEXT: entry: 35; CHECK-NEXT: br label [[FOR_BODY:%.*]] 36; CHECK: for.body: 37; CHECK-NEXT: [[ZEXT_9:%.*]] = zext i8 [[A:%.*]] to i32 38; CHECK-NEXT: [[AND_9:%.*]] = and i32 [[ZEXT_9]], 31 39; CHECK-NEXT: [[SHL_9:%.*]] = shl i32 [[AND_9]], 15 40; CHECK-NEXT: ret i32 [[SHL_9]] 41; 42entry: 43 br label %for.body 44 45for.body: 46 %phi = phi i64 [ 0, %entry ], [ %inc, %for.body ] 47 %zext = zext i8 %a to i32 48 %and = and i32 %zext, 31 49 %shl = shl i32 %and, 15 50 %inc = add nuw nsw i64 %phi, 1 51 %cmp = icmp ult i64 %inc, 10 52 br i1 %cmp, label %for.body, label %for.exit 53 54for.exit: 55 ret i32 %shl 56} 57 58; Show that this works for instructions which might fault as well 59define i32 @test3(i8 %a) { 60; CHECK-LABEL: @test3( 61; CHECK-NEXT: entry: 62; CHECK-NEXT: br label [[FOR_BODY:%.*]] 63; CHECK: for.body: 64; CHECK-NEXT: [[ZEXT_9:%.*]] = zext i8 [[A:%.*]] to i32 65; CHECK-NEXT: [[DIV_9:%.*]] = udiv i32 [[ZEXT_9]], 31 66; CHECK-NEXT: ret i32 [[DIV_9]] 67; 68entry: 69 br label %for.body 70 71for.body: 72 %phi = phi i64 [ 0, %entry ], [ %inc, %for.body ] 73 %zext = zext i8 %a to i32 74 %div = udiv i32 %zext, 31 75 %inc = add nuw nsw i64 %phi, 1 76 %cmp = icmp ult i64 %inc, 10 77 br i1 %cmp, label %for.body, label %for.exit 78 79for.exit: 80 ret i32 %div 81} 82