|
1 |
| -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 |
| 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
2 | 2 | ; RUN: opt -p loop-idiom -S %s | FileCheck %s
|
3 | 3 |
|
4 | 4 | define void @fold_add_zext_to_sext(ptr %dst, i1 %start) {
|
|
40 | 40 | exit:
|
41 | 41 | ret void
|
42 | 42 | }
|
| 43 | + |
| 44 | +declare i16 @get() |
| 45 | + |
| 46 | +define void @test_memset_size_can_use_info_from_guards(i32 %x, ptr %dst) { |
| 47 | +; CHECK-LABEL: define void @test_memset_size_can_use_info_from_guards( |
| 48 | +; CHECK-SAME: i32 [[X:%.*]], ptr [[DST:%.*]]) { |
| 49 | +; CHECK-NEXT: [[ENTRY:.*]]: |
| 50 | +; CHECK-NEXT: br label %[[LOOP1:.*]] |
| 51 | +; CHECK: [[LOOP1_LOOPEXIT:.*]]: |
| 52 | +; CHECK-NEXT: br label %[[LOOP1_BACKEDGE:.*]] |
| 53 | +; CHECK: [[LOOP1]]: |
| 54 | +; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[X]], %[[LOOP1_BACKEDGE]] ] |
| 55 | +; CHECK-NEXT: [[L:%.*]] = call i16 @get() |
| 56 | +; CHECK-NEXT: [[L_EXT:%.*]] = zext i16 [[L]] to i32 |
| 57 | +; CHECK-NEXT: [[SUB:%.*]] = sub i32 [[L_EXT]], [[P]] |
| 58 | +; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[SUB]], 1 |
| 59 | +; CHECK-NEXT: [[EC:%.*]] = icmp ult i32 [[SUB]], 2 |
| 60 | +; CHECK-NEXT: br i1 [[EC]], label %[[LOOP1_BACKEDGE]], label %[[LOOP2_PREHEADER:.*]] |
| 61 | +; CHECK: [[LOOP1_BACKEDGE]]: |
| 62 | +; CHECK-NEXT: br label %[[LOOP1]] |
| 63 | +; CHECK: [[LOOP2_PREHEADER]]: |
| 64 | +; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[SUB]] to i64 |
| 65 | +; CHECK-NEXT: [[TMP1:%.*]] = lshr i64 [[TMP0]], 1 |
| 66 | +; CHECK-NEXT: [[UMAX:%.*]] = call i64 @llvm.umax.i64(i64 [[TMP1]], i64 1) |
| 67 | +; CHECK-NEXT: call void @llvm.memset.p0.i64(ptr align 1 [[DST]], i8 0, i64 [[UMAX]], i1 false) |
| 68 | +; CHECK-NEXT: br label %[[LOOP2:.*]] |
| 69 | +; CHECK: [[LOOP2]]: |
| 70 | +; CHECK-NEXT: [[IV_2:%.*]] = phi i32 [ [[IV_2_NEXT:%.*]], %[[LOOP2]] ], [ 0, %[[LOOP2_PREHEADER]] ] |
| 71 | +; CHECK-NEXT: [[GEP_DST:%.*]] = getelementptr i8, ptr [[DST]], i32 [[IV_2]] |
| 72 | +; CHECK-NEXT: [[IV_2_NEXT]] = add i32 [[IV_2]], 1 |
| 73 | +; CHECK-NEXT: [[EC_2:%.*]] = icmp ult i32 [[IV_2_NEXT]], [[SHR]] |
| 74 | +; CHECK-NEXT: br i1 [[EC_2]], label %[[LOOP2]], label %[[LOOP1_LOOPEXIT]] |
| 75 | +; |
| 76 | +entry: |
| 77 | + br label %loop1 |
| 78 | + |
| 79 | +loop1: |
| 80 | + %p = phi i32 [ 0, %entry ], [ %x, %loop1 ], [ %x, %loop2 ] |
| 81 | + %l = call i16 @get() |
| 82 | + %l.ext = zext i16 %l to i32 |
| 83 | + %sub = sub i32 %l.ext, %p |
| 84 | + %shr = lshr i32 %sub, 1 |
| 85 | + %ec = icmp ult i32 %sub, 2 |
| 86 | + br i1 %ec, label %loop1, label %loop2 |
| 87 | + |
| 88 | +loop2: |
| 89 | + %iv.2 = phi i32 [ 0, %loop1 ], [ %iv.2.next, %loop2 ] |
| 90 | + %gep.dst = getelementptr i8, ptr %dst, i32 %iv.2 |
| 91 | + store i8 0, ptr %gep.dst, align 1 |
| 92 | + %iv.2.next = add i32 %iv.2, 1 |
| 93 | + %ec.2 = icmp ult i32 %iv.2.next, %shr |
| 94 | + br i1 %ec.2, label %loop2, label %loop1 |
| 95 | +} |
0 commit comments