Johannes Doerfert | a41b239 | 2019-08-21 21:42:46 +0000 | [diff] [blame] | 1 | ; RUN: opt -attributor --attributor-disable=false -attributor-max-iterations=4 -S < %s | FileCheck %s --check-prefixes=ATTRIBUTOR |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 2 | |
| 3 | |
Johannes Doerfert | 785fad3 | 2019-08-23 17:29:23 +0000 | [diff] [blame^] | 4 | declare void @deref_phi_user(i32* %a); |
| 5 | |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 6 | ; TEST 1 |
| 7 | ; take mininimum of return values |
| 8 | ; |
Tim Northover | a009a60 | 2019-08-03 14:28:34 +0000 | [diff] [blame] | 9 | define i32* @test1(i32* dereferenceable(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr { |
| 10 | ; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test1(i32* nonnull dereferenceable(4) %0, double* nonnull dereferenceable(8) %1, i1 zeroext %2) |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 11 | %4 = bitcast double* %1 to i32* |
| 12 | %5 = select i1 %2, i32* %0, i32* %4 |
| 13 | ret i32* %5 |
| 14 | } |
| 15 | |
| 16 | ; TEST 2 |
Tim Northover | a009a60 | 2019-08-03 14:28:34 +0000 | [diff] [blame] | 17 | define i32* @test2(i32* dereferenceable_or_null(4) %0, double* dereferenceable(8) %1, i1 zeroext %2) local_unnamed_addr { |
| 18 | ; ATTRIBUTOR: define dereferenceable_or_null(4) i32* @test2(i32* dereferenceable_or_null(4) %0, double* nonnull dereferenceable(8) %1, i1 zeroext %2) |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 19 | %4 = bitcast double* %1 to i32* |
| 20 | %5 = select i1 %2, i32* %0, i32* %4 |
| 21 | ret i32* %5 |
| 22 | } |
| 23 | |
| 24 | ; TEST 3 |
| 25 | ; GEP inbounds |
Tim Northover | a009a60 | 2019-08-03 14:28:34 +0000 | [diff] [blame] | 26 | define i32* @test3_1(i32* dereferenceable(8) %0) local_unnamed_addr { |
Johannes Doerfert | 12cbbab | 2019-08-20 06:15:50 +0000 | [diff] [blame] | 27 | ; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_1(i32* nonnull dereferenceable(8) %0) |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 28 | %ret = getelementptr inbounds i32, i32* %0, i64 1 |
| 29 | ret i32* %ret |
| 30 | } |
| 31 | |
Tim Northover | a009a60 | 2019-08-03 14:28:34 +0000 | [diff] [blame] | 32 | define i32* @test3_2(i32* dereferenceable_or_null(32) %0) local_unnamed_addr { |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 33 | ; FIXME: Argument should be mark dereferenceable because of GEP `inbounds`. |
Johannes Doerfert | 12cbbab | 2019-08-20 06:15:50 +0000 | [diff] [blame] | 34 | ; ATTRIBUTOR: define nonnull dereferenceable(16) i32* @test3_2(i32* dereferenceable_or_null(32) %0) |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 35 | %ret = getelementptr inbounds i32, i32* %0, i64 4 |
| 36 | ret i32* %ret |
| 37 | } |
| 38 | |
Tim Northover | a009a60 | 2019-08-03 14:28:34 +0000 | [diff] [blame] | 39 | define i32* @test3_3(i32* dereferenceable(8) %0, i32* dereferenceable(16) %1, i1 %2) local_unnamed_addr { |
Johannes Doerfert | 12cbbab | 2019-08-20 06:15:50 +0000 | [diff] [blame] | 40 | ; ATTRIBUTOR: define nonnull dereferenceable(4) i32* @test3_3(i32* nonnull dereferenceable(8) %0, i32* nonnull dereferenceable(16) %1, i1 %2) local_unnamed_addr |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 41 | %ret1 = getelementptr inbounds i32, i32* %0, i64 1 |
| 42 | %ret2 = getelementptr inbounds i32, i32* %1, i64 2 |
| 43 | %ret = select i1 %2, i32* %ret1, i32* %ret2 |
| 44 | ret i32* %ret |
| 45 | } |
| 46 | |
| 47 | ; TEST 4 |
| 48 | ; Better than known in IR. |
| 49 | |
Tim Northover | a009a60 | 2019-08-03 14:28:34 +0000 | [diff] [blame] | 50 | define dereferenceable(4) i32* @test4(i32* dereferenceable(8) %0) local_unnamed_addr { |
| 51 | ; ATTRIBUTOR: define nonnull dereferenceable(8) i32* @test4(i32* nonnull returned dereferenceable(8) %0) |
Hideto Ueno | 19c07af | 2019-07-23 08:16:17 +0000 | [diff] [blame] | 52 | ret i32* %0 |
| 53 | } |
| 54 | |
Johannes Doerfert | 2f2d7c3 | 2019-08-23 15:45:46 +0000 | [diff] [blame] | 55 | ; TEST 5 |
| 56 | ; loop in which dereferenceabily "grows" |
Johannes Doerfert | 785fad3 | 2019-08-23 17:29:23 +0000 | [diff] [blame^] | 57 | define void @deref_phi_growing(i32* dereferenceable(4000) %a) { |
Johannes Doerfert | 2f2d7c3 | 2019-08-23 15:45:46 +0000 | [diff] [blame] | 58 | entry: |
| 59 | br label %for.cond |
| 60 | |
| 61 | for.cond: ; preds = %for.inc, %entry |
| 62 | %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] |
| 63 | %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ] |
| 64 | ; CHECK: call void @deref_phi_user(i32* dereferenceable(4000) %a.addr.0) |
| 65 | call void @deref_phi_user(i32* %a.addr.0) |
| 66 | %tmp = load i32, i32* %a.addr.0, align 4 |
| 67 | %cmp = icmp slt i32 %i.0, %tmp |
| 68 | br i1 %cmp, label %for.body, label %for.cond.cleanup |
| 69 | |
| 70 | for.cond.cleanup: ; preds = %for.cond |
| 71 | br label %for.end |
| 72 | |
| 73 | for.body: ; preds = %for.cond |
| 74 | br label %for.inc |
| 75 | |
| 76 | for.inc: ; preds = %for.body |
| 77 | %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 -1 |
| 78 | %inc = add nuw nsw i32 %i.0, 1 |
| 79 | br label %for.cond |
| 80 | |
| 81 | for.end: ; preds = %for.cond.cleanup |
| 82 | ret void |
| 83 | } |
Johannes Doerfert | 785fad3 | 2019-08-23 17:29:23 +0000 | [diff] [blame^] | 84 | |
| 85 | ; TEST 6 |
| 86 | ; loop in which dereferenceabily "shrinks" |
| 87 | define void @deref_phi_shrinking(i32* dereferenceable(4000) %a) { |
| 88 | entry: |
| 89 | br label %for.cond |
| 90 | |
| 91 | for.cond: ; preds = %for.inc, %entry |
| 92 | %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] |
| 93 | %a.addr.0 = phi i32* [ %a, %entry ], [ %incdec.ptr, %for.inc ] |
| 94 | ; CHECK: call void @deref_phi_user(i32* %a.addr.0) |
| 95 | call void @deref_phi_user(i32* %a.addr.0) |
| 96 | %tmp = load i32, i32* %a.addr.0, align 4 |
| 97 | %cmp = icmp slt i32 %i.0, %tmp |
| 98 | br i1 %cmp, label %for.body, label %for.cond.cleanup |
| 99 | |
| 100 | for.cond.cleanup: ; preds = %for.cond |
| 101 | br label %for.end |
| 102 | |
| 103 | for.body: ; preds = %for.cond |
| 104 | br label %for.inc |
| 105 | |
| 106 | for.inc: ; preds = %for.body |
| 107 | %incdec.ptr = getelementptr inbounds i32, i32* %a.addr.0, i64 1 |
| 108 | %inc = add nuw nsw i32 %i.0, 1 |
| 109 | br label %for.cond |
| 110 | |
| 111 | for.end: ; preds = %for.cond.cleanup |
| 112 | ret void |
| 113 | } |