1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -basicaa -newgvn -S | FileCheck %s 3target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" 4 5;; Function Attrs: nounwind ssp uwtable 6;; We should eliminate the sub, and one of the phi nodes 7define void @vnum_test1(i32* %data) #0 { 8; CHECK-LABEL: @vnum_test1( 9; CHECK-NEXT: bb: 10; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 3 11; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 12; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 4 13; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 14; CHECK-NEXT: br label [[BB4:%.*]] 15; CHECK: bb4: 16; CHECK-NEXT: [[M_0:%.*]] = phi i32 [ [[TMP3]], [[BB:%.*]] ], [ [[TMP15:%.*]], [[BB17:%.*]] ] 17; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP18:%.*]], [[BB17]] ] 18; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[I_0]], [[TMP1]] 19; CHECK-NEXT: br i1 [[TMP5]], label [[BB6:%.*]], label [[BB19:%.*]] 20; CHECK: bb6: 21; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 2 22; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4 23; CHECK-NEXT: [[TMP9:%.*]] = sext i32 [[TMP8]] to i64 24; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 [[TMP9]] 25; CHECK-NEXT: store i32 2, i32* [[TMP10]], align 4 26; CHECK-NEXT: store i32 0, i32* [[DATA]], align 4 27; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 1 28; CHECK-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4 29; CHECK-NEXT: [[TMP15]] = add nsw i32 [[M_0]], [[TMP14]] 30; CHECK-NEXT: br label [[BB17]] 31; CHECK: bb17: 32; CHECK-NEXT: [[TMP18]] = add nsw i32 [[I_0]], 1 33; CHECK-NEXT: br label [[BB4]] 34; CHECK: bb19: 35; CHECK-NEXT: ret void 36; 37bb: 38 %tmp = getelementptr inbounds i32, i32* %data, i64 3 39 %tmp1 = load i32, i32* %tmp, align 4 40 %tmp2 = getelementptr inbounds i32, i32* %data, i64 4 41 %tmp3 = load i32, i32* %tmp2, align 4 42 br label %bb4 43 44bb4: ; preds = %bb17, %bb 45 %m.0 = phi i32 [ %tmp3, %bb ], [ %tmp15, %bb17 ] 46 %i.0 = phi i32 [ 0, %bb ], [ %tmp18, %bb17 ] 47 %n.0 = phi i32 [ %tmp3, %bb ], [ %tmp16, %bb17 ] 48 %tmp5 = icmp slt i32 %i.0, %tmp1 49 br i1 %tmp5, label %bb6, label %bb19 50 51bb6: ; preds = %bb4 52 %tmp7 = getelementptr inbounds i32, i32* %data, i64 2 53 %tmp8 = load i32, i32* %tmp7, align 4 54 %tmp9 = sext i32 %tmp8 to i64 55 %tmp10 = getelementptr inbounds i32, i32* %data, i64 %tmp9 56 store i32 2, i32* %tmp10, align 4 57 %tmp11 = sub nsw i32 %m.0, %n.0 58 %tmp12 = getelementptr inbounds i32, i32* %data, i64 0 59 store i32 %tmp11, i32* %tmp12, align 4 60 %tmp13 = getelementptr inbounds i32, i32* %data, i64 1 61 %tmp14 = load i32, i32* %tmp13, align 4 62 %tmp15 = add nsw i32 %m.0, %tmp14 63 %tmp16 = add nsw i32 %n.0, %tmp14 64 br label %bb17 65 66bb17: ; preds = %bb6 67 %tmp18 = add nsw i32 %i.0, 1 68 br label %bb4 69 70bb19: ; preds = %bb4 71 ret void 72} 73 74;; Function Attrs: nounwind ssp uwtable 75;; We should eliminate the sub, one of the phi nodes, prove the store of the sub 76;; and the load of data are equivalent, that the load always produces constant 0, and 77;; delete the load replacing it with constant 0. 78define i32 @vnum_test2(i32* %data) #0 { 79; CHECK-LABEL: @vnum_test2( 80; CHECK-NEXT: bb: 81; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 3 82; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 83; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 4 84; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 85; CHECK-NEXT: br label [[BB4:%.*]] 86; CHECK: bb4: 87; CHECK-NEXT: [[M_0:%.*]] = phi i32 [ [[TMP3]], [[BB:%.*]] ], [ [[TMP15:%.*]], [[BB19:%.*]] ] 88; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP20:%.*]], [[BB19]] ] 89; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[I_0]], [[TMP1]] 90; CHECK-NEXT: br i1 [[TMP5]], label [[BB6:%.*]], label [[BB21:%.*]] 91; CHECK: bb6: 92; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 2 93; CHECK-NEXT: [[TMP8:%.*]] = load i32, i32* [[TMP7]], align 4 94; CHECK-NEXT: [[TMP9:%.*]] = sext i32 [[TMP8]] to i64 95; CHECK-NEXT: [[TMP10:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 [[TMP9]] 96; CHECK-NEXT: store i32 2, i32* [[TMP10]], align 4 97; CHECK-NEXT: store i32 0, i32* [[DATA]], align 4 98; CHECK-NEXT: [[TMP13:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 1 99; CHECK-NEXT: [[TMP14:%.*]] = load i32, i32* [[TMP13]], align 4 100; CHECK-NEXT: [[TMP15]] = add nsw i32 [[M_0]], [[TMP14]] 101; CHECK-NEXT: br label [[BB19]] 102; CHECK: bb19: 103; CHECK-NEXT: [[TMP20]] = add nsw i32 [[I_0]], 1 104; CHECK-NEXT: br label [[BB4]] 105; CHECK: bb21: 106; CHECK-NEXT: ret i32 0 107; 108bb: 109 %tmp = getelementptr inbounds i32, i32* %data, i64 3 110 %tmp1 = load i32, i32* %tmp, align 4 111 %tmp2 = getelementptr inbounds i32, i32* %data, i64 4 112 %tmp3 = load i32, i32* %tmp2, align 4 113 br label %bb4 114 115bb4: ; preds = %bb19, %bb 116 %m.0 = phi i32 [ %tmp3, %bb ], [ %tmp15, %bb19 ] 117 %n.0 = phi i32 [ %tmp3, %bb ], [ %tmp16, %bb19 ] 118 %i.0 = phi i32 [ 0, %bb ], [ %tmp20, %bb19 ] 119 %p.0 = phi i32 [ undef, %bb ], [ %tmp18, %bb19 ] 120 %tmp5 = icmp slt i32 %i.0, %tmp1 121 br i1 %tmp5, label %bb6, label %bb21 122 123bb6: ; preds = %bb4 124 %tmp7 = getelementptr inbounds i32, i32* %data, i64 2 125 %tmp8 = load i32, i32* %tmp7, align 4 126 %tmp9 = sext i32 %tmp8 to i64 127 %tmp10 = getelementptr inbounds i32, i32* %data, i64 %tmp9 128 store i32 2, i32* %tmp10, align 4 129 %tmp11 = sub nsw i32 %m.0, %n.0 130 %tmp12 = getelementptr inbounds i32, i32* %data, i64 0 131 store i32 %tmp11, i32* %tmp12, align 4 132 %tmp13 = getelementptr inbounds i32, i32* %data, i64 1 133 %tmp14 = load i32, i32* %tmp13, align 4 134 %tmp15 = add nsw i32 %m.0, %tmp14 135 %tmp16 = add nsw i32 %n.0, %tmp14 136 %tmp17 = getelementptr inbounds i32, i32* %data, i64 0 137 %tmp18 = load i32, i32* %tmp17, align 4 138 br label %bb19 139 140bb19: ; preds = %bb6 141 %tmp20 = add nsw i32 %i.0, 1 142 br label %bb4 143 144bb21: ; preds = %bb4 145 ret i32 %p.0 146} 147 148 149; Function Attrs: nounwind ssp uwtable 150;; Same as test 2, with a conditional store of m-n, so it has to also discover 151;; that data ends up with the same value no matter what branch is taken. 152define i32 @vnum_test3(i32* %data) #0 { 153; CHECK-LABEL: @vnum_test3( 154; CHECK-NEXT: bb: 155; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds i32, i32* [[DATA:%.*]], i64 3 156; CHECK-NEXT: [[TMP1:%.*]] = load i32, i32* [[TMP]], align 4 157; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 4 158; CHECK-NEXT: [[TMP3:%.*]] = load i32, i32* [[TMP2]], align 4 159; CHECK-NEXT: br label [[BB4:%.*]] 160; CHECK: bb4: 161; CHECK-NEXT: [[N_0:%.*]] = phi i32 [ [[TMP3]], [[BB:%.*]] ], [ [[TMP19:%.*]], [[BB21:%.*]] ] 162; CHECK-NEXT: [[I_0:%.*]] = phi i32 [ 0, [[BB]] ], [ [[TMP22:%.*]], [[BB21]] ] 163; CHECK-NEXT: [[TMP5:%.*]] = icmp slt i32 [[I_0]], [[TMP1]] 164; CHECK-NEXT: br i1 [[TMP5]], label [[BB6:%.*]], label [[BB23:%.*]] 165; CHECK: bb6: 166; CHECK-NEXT: [[TMP7:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 2 167; CHECK-NEXT: [[TMP9:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 5 168; CHECK-NEXT: store i32 0, i32* [[TMP9]], align 4 169; CHECK-NEXT: [[TMP10:%.*]] = icmp slt i32 [[I_0]], 30 170; CHECK-NEXT: br i1 [[TMP10]], label [[BB11:%.*]], label [[BB14:%.*]] 171; CHECK: bb11: 172; CHECK-NEXT: store i32 0, i32* [[TMP9]], align 4 173; CHECK-NEXT: br label [[BB14]] 174; CHECK: bb14: 175; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds i32, i32* [[DATA]], i64 1 176; CHECK-NEXT: [[TMP18:%.*]] = load i32, i32* [[TMP17]], align 4 177; CHECK-NEXT: [[TMP19]] = add nsw i32 [[N_0]], [[TMP18]] 178; CHECK-NEXT: br label [[BB21]] 179; CHECK: bb21: 180; CHECK-NEXT: [[TMP22]] = add nsw i32 [[I_0]], 1 181; CHECK-NEXT: br label [[BB4]] 182; CHECK: bb23: 183; CHECK-NEXT: ret i32 0 184; 185bb: 186 %tmp = getelementptr inbounds i32, i32* %data, i64 3 187 %tmp1 = load i32, i32* %tmp, align 4 188 %tmp2 = getelementptr inbounds i32, i32* %data, i64 4 189 %tmp3 = load i32, i32* %tmp2, align 4 190 br label %bb4 191 192bb4: ; preds = %bb21, %bb 193 %n.0 = phi i32 [ %tmp3, %bb ], [ %tmp20, %bb21 ] 194 %m.0 = phi i32 [ %tmp3, %bb ], [ %tmp19, %bb21 ] 195 %p.0 = phi i32 [ 0, %bb ], [ %tmp16, %bb21 ] 196 %i.0 = phi i32 [ 0, %bb ], [ %tmp22, %bb21 ] 197 %tmp5 = icmp slt i32 %i.0, %tmp1 198 br i1 %tmp5, label %bb6, label %bb23 199 200bb6: ; preds = %bb4 201 %tmp7 = getelementptr inbounds i32, i32* %data, i64 2 202 %tmp8 = load i32, i32* %tmp7, align 4 203 %tmp9 = getelementptr inbounds i32, i32* %data, i64 5 204 store i32 0, i32* %tmp9, align 4 205 %tmp10 = icmp slt i32 %i.0, 30 206 br i1 %tmp10, label %bb11, label %bb14 207 208bb11: ; preds = %bb6 209 %tmp12 = sub nsw i32 %m.0, %n.0 210 %tmp13 = getelementptr inbounds i32, i32* %data, i64 5 211 store i32 %tmp12, i32* %tmp13, align 4 212 br label %bb14 213 214bb14: ; preds = %bb11, %bb6 215 %tmp15 = getelementptr inbounds i32, i32* %data, i64 5 216 %tmp16 = load i32, i32* %tmp15, align 4 217 %tmp17 = getelementptr inbounds i32, i32* %data, i64 1 218 %tmp18 = load i32, i32* %tmp17, align 4 219 %tmp19 = add nsw i32 %m.0, %tmp18 220 %tmp20 = add nsw i32 %n.0, %tmp18 221 br label %bb21 222 223bb21: ; preds = %bb14 224 %tmp22 = add nsw i32 %i.0, 1 225 br label %bb4 226 227bb23: ; preds = %bb4 228 ret i32 %p.0 229} 230 231attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } 232 233!llvm.ident = !{!0, !0, !0} 234 235!0 = !{!"Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)"} 236