1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -S -mtriple=x86_64-linux < %s | FileCheck %s 3 4define i32 @test1(ptr %d) nounwind { 5; CHECK-LABEL: @test1( 6; CHECK-NEXT: entry: 7; CHECK-NEXT: [[L:%.*]] = load i8, ptr [[D:%.*]], align 1 8; CHECK-NEXT: [[TMP0:%.*]] = icmp eq i8 [[L]], 0 9; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[TMP0]] to i32 10; CHECK-NEXT: ret i32 [[CONV]] 11; 12entry: 13 %l = load i8, ptr %d 14 %cmp = icmp eq i8 %l, 0 15 br i1 %cmp, label %exit, label %if.end 16 17if.end: 18 %gep = getelementptr i8, ptr %d, i32 42 19 %call = call i64 @foo(ptr %gep) nounwind readonly willreturn 20 %cmp2 = icmp ne i64 %call, 0 21 call void @llvm.assume(i1 %cmp2) 22 br label %exit 23 24exit: 25 %conv = zext i1 %cmp to i32 26 ret i32 %conv 27} 28 29define i32 @test2(i32 %N) nounwind { 30; CHECK-LABEL: @test2( 31; CHECK-NEXT: entry: 32; CHECK-NEXT: br label [[HEADER:%.*]] 33; CHECK: header: 34; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[HEADER]] ] 35; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1 36; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[IV]], [[N:%.*]] 37; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[HEADER]] 38; CHECK: exit: 39; CHECK-NEXT: ret i32 [[IV]] 40; 41entry: 42 br label %header 43 44header: 45 %iv = phi i32 [0, %entry], [%iv.inc, %header] 46 %iv2 = phi i32 [0, %entry], [%iv2.inc, %header] 47 %iv.inc = add i32 %iv, 1 48 %iv2.inc = add i32 %iv2, 1 49 %cmp = icmp eq i32 %iv, %N 50 %cmp2 = icmp sle i32 %iv2, %N 51 call void @llvm.assume(i1 %cmp2) 52 br i1 %cmp, label %exit, label %header 53 54exit: 55 ret i32 %iv 56} 57 58define i32 @test3(i32 %N) nounwind { 59; CHECK-LABEL: @test3( 60; CHECK-NEXT: entry: 61; CHECK-NEXT: br label [[HEADER:%.*]] 62; CHECK: header: 63; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[HEADER]] ] 64; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1 65; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[IV]], [[N:%.*]] 66; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[HEADER]] 67; CHECK: exit: 68; CHECK-NEXT: ret i32 [[IV]] 69; 70entry: 71 br label %header 72 73header: 74 %iv = phi i32 [0, %entry], [%iv.inc, %header] 75 %iv2 = phi i32 [0, %entry], [%iv2.inc, %header] 76 %iv.inc = add i32 %iv, 1 77 %iv2.inc = add i32 %iv2, 1 78 %cmp = icmp eq i32 %iv, %N 79 %cmp2 = icmp sle i32 %iv2.inc, %N 80 call void @llvm.assume(i1 %cmp2) 81 br i1 %cmp, label %exit, label %header 82 83exit: 84 ret i32 %iv 85} 86 87; Two assumes case. 88define i32 @test4(i32 %N) nounwind { 89; CHECK-LABEL: @test4( 90; CHECK-NEXT: entry: 91; CHECK-NEXT: br label [[HEADER:%.*]] 92; CHECK: header: 93; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[HEADER]] ] 94; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1 95; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[IV]], [[N:%.*]] 96; CHECK-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[HEADER]] 97; CHECK: exit: 98; CHECK-NEXT: ret i32 [[IV]] 99; 100entry: 101 br label %header 102 103header: 104 %iv = phi i32 [0, %entry], [%iv.inc, %header] 105 %iv2 = phi i32 [0, %entry], [%iv2.inc, %header] 106 %iv.inc = add i32 %iv, 1 107 %iv2.inc = add i32 %iv2, 1 108 %cmp = icmp eq i32 %iv, %N 109 %cmp2 = icmp sle i32 %iv2.inc, %N 110 call void @llvm.assume(i1 %cmp2) 111 %cmp3 = icmp sge i32 %iv2.inc, 0 112 call void @llvm.assume(i1 %cmp3) 113 br i1 %cmp, label %exit, label %header 114 115exit: 116 ret i32 %iv 117} 118 119; phi is used in assume and in compare. 120define i32 @test5(i32 %N, i32 %M) nounwind { 121; CHECK-LABEL: @test5( 122; CHECK-NEXT: entry: 123; CHECK-NEXT: br label [[HEADER:%.*]] 124; CHECK: header: 125; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_INC:%.*]], [[HEADER]] ] 126; CHECK-NEXT: [[IV2:%.*]] = phi i32 [ 0, [[ENTRY]] ], [ [[IV2_INC:%.*]], [[HEADER]] ] 127; CHECK-NEXT: [[IV_INC]] = add i32 [[IV]], 1 128; CHECK-NEXT: [[IV2_INC]] = add i32 [[IV2]], 1 129; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[IV]], [[N:%.*]] 130; CHECK-NEXT: [[CMP3:%.*]] = icmp sge i32 [[IV2_INC]], [[M:%.*]] 131; CHECK-NEXT: [[CMP4:%.*]] = and i1 [[CMP]], [[CMP3]] 132; CHECK-NEXT: br i1 [[CMP4]], label [[EXIT:%.*]], label [[HEADER]] 133; CHECK: exit: 134; CHECK-NEXT: ret i32 [[IV]] 135; 136entry: 137 br label %header 138 139header: 140 %iv = phi i32 [0, %entry], [%iv.inc, %header] 141 %iv2 = phi i32 [0, %entry], [%iv2.inc, %header] 142 %iv.inc = add i32 %iv, 1 143 %iv2.inc = add i32 %iv2, 1 144 %cmp = icmp eq i32 %iv, %N 145 %cmp2 = icmp sle i32 %iv2.inc, %N 146 call void @llvm.assume(i1 %cmp2) 147 %cmp3 = icmp sge i32 %iv2.inc, %M 148 %cmp4 = and i1 %cmp, %cmp3 149 br i1 %cmp4, label %exit, label %header 150 151exit: 152 ret i32 %iv 153} 154 155declare i64 @foo(ptr) nounwind readonly willreturn 156declare void @llvm.assume(i1 noundef) nounwind willreturn 157