Index: llvm/test/Transforms/GVN/condprop.ll =================================================================== --- llvm/test/Transforms/GVN/condprop.ll +++ llvm/test/Transforms/GVN/condprop.ll @@ -512,9 +512,7 @@ ret i32 %res } -; On the path from entry->if->end we know that ptr1==ptr2, so we can determine -; that gep2 does not alias ptr1 on that path (as it would require that -; ptr2==ptr2+2), so we can perform PRE of the load. +; Check that we dont propagate pointer equalities when illegal. define i32 @test13(ptr %ptr1, ptr %ptr2) { ; CHECK-LABEL: @test13( ; CHECK-NEXT: entry: @@ -556,14 +554,14 @@ ret i32 %ret } -define void @test14(ptr %ptr1, ptr noalias %ptr2) { +define void @test14(ptr %ptr1, ptr noalias %ptr2, i1 %c1, i1 %c2) { ; CHECK-LABEL: @test14( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[PTR1:%.*]], i32 1 ; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 2 ; CHECK-NEXT: br label [[LOOP:%.*]] ; CHECK: loop: -; CHECK-NEXT: br i1 undef, label [[LOOP_IF1_CRIT_EDGE:%.*]], label [[THEN:%.*]] +; CHECK-NEXT: br i1 [[C1:%.*]], label [[LOOP_IF1_CRIT_EDGE:%.*]], label [[THEN:%.*]] ; CHECK: loop.if1_crit_edge: ; CHECK-NEXT: [[VAL2_PRE:%.*]] = load i32, ptr [[GEP2]], align 4 ; CHECK-NEXT: br label [[IF1:%.*]] @@ -581,7 +579,7 @@ ; CHECK-NEXT: [[PHI3:%.*]] = phi ptr [ [[PTR2]], [[THEN]] ], [ [[PTR1]], [[IF2]] ] ; CHECK-NEXT: [[VAL3]] = load i32, ptr [[GEP2]], align 4 ; CHECK-NEXT: store i32 [[VAL3]], ptr [[PHI3]], align 4 -; CHECK-NEXT: br i1 undef, label [[LOOP]], label [[IF1]] +; CHECK-NEXT: br i1 [[C2:%.*]], label [[LOOP]], label [[IF1]] ; entry: %gep1 = getelementptr inbounds i32, ptr %ptr1, i32 1 @@ -590,7 +588,7 @@ loop: %phi1 = phi ptr [ %gep3, %loop.end ], [ %gep1, %entry ] - br i1 undef, label %if1, label %then + br i1 %c1, label %if1, label %then if1: @@ -611,5 +609,204 @@ %val3 = load i32, ptr %gep2, align 4 store i32 %val3, ptr %phi3, align 4 %gep3 = getelementptr inbounds i32, ptr %ptr1, i32 1 - br i1 undef, label %loop, label %if1 + br i1 %c2, label %loop, label %if1 } + +define void @single_phi1(ptr %p1) { +; CHECK-LABEL: @single_phi1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr poison, align 8 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[P2]], [[P1:%.*]] +; CHECK-NEXT: br i1 [[CMP1]], label [[BB4:%.*]], label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: switch i8 poison, label [[BB2:%.*]] [ +; CHECK-NEXT: i8 0, label [[BB1]] +; CHECK-NEXT: i8 1, label [[BB3:%.*]] +; CHECK-NEXT: ] +; CHECK: bb2: +; CHECK-NEXT: unreachable +; CHECK: bb3: +; CHECK-NEXT: br label [[BB4]] +; CHECK: bb4: +; CHECK-NEXT: call void @use_bool(i1 true) +; CHECK-NEXT: call void @use_ptr(ptr [[P1]]) +; CHECK-NEXT: ret void +; +entry: + %p2 = load ptr, ptr poison, align 8 + %cmp1 = icmp eq ptr %p2, %p1 + br i1 %cmp1, label %bb4, label %bb1 + +bb1: + switch i8 poison, label %bb2 [ + i8 0, label %bb1 + i8 1, label %bb3 + ] + +bb2: + unreachable + +bb3: + br label %bb4 + +bb4: + %phi1 = phi ptr [ %p2, %entry ], [ poison, %bb3 ] + %cmp2 = icmp eq ptr %phi1, %p1 + call void @use_bool(i1 %cmp2) + call void @use_ptr(ptr %phi1) + ret void +} + +define void @single_phi2(ptr %p1) { +; CHECK-LABEL: @single_phi2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr poison, align 8 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[P2]], [[P1:%.*]] +; CHECK-NEXT: br i1 [[CMP1]], label [[BB4:%.*]], label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: switch i8 poison, label [[BB2:%.*]] [ +; CHECK-NEXT: i8 0, label [[BB1]] +; CHECK-NEXT: i8 1, label [[BB3:%.*]] +; CHECK-NEXT: ] +; CHECK: bb2: +; CHECK-NEXT: br label [[BB4]] +; CHECK: bb3: +; CHECK-NEXT: br label [[BB4]] +; CHECK: bb4: +; CHECK-NEXT: [[PHI1:%.*]] = phi ptr [ [[P1]], [[ENTRY:%.*]] ], [ [[P2]], [[BB2]] ], [ poison, [[BB3]] ] +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[PHI1]], [[P1]] +; CHECK-NEXT: call void @use_bool(i1 [[CMP2]]) +; CHECK-NEXT: call void @use_ptr(ptr [[PHI1]]) +; CHECK-NEXT: ret void +; +entry: + %p2 = load ptr, ptr poison, align 8 + %cmp1 = icmp eq ptr %p2, %p1 + br i1 %cmp1, label %bb4, label %bb1 + +bb1: + switch i8 poison, label %bb2 [ + i8 0, label %bb1 + i8 1, label %bb3 + ] + +bb2: + br label %bb4 + +bb3: + br label %bb4 + +bb4: + %phi1 = phi ptr [ %p2, %entry ], [ %p2, %bb2 ], [ poison, %bb3 ] + %cmp2 = icmp eq ptr %phi1, %p1 + call void @use_bool(i1 %cmp2) + call void @use_ptr(ptr %phi1) + ret void +} + +define void @multiple_phi1(ptr %p1) { +; CHECK-LABEL: @multiple_phi1( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr poison, align 8 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[P2]], [[P1:%.*]] +; CHECK-NEXT: br i1 [[CMP1]], label [[BB4:%.*]], label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: switch i8 poison, label [[BB2:%.*]] [ +; CHECK-NEXT: i8 0, label [[BB1]] +; CHECK-NEXT: i8 1, label [[BB3:%.*]] +; CHECK-NEXT: ] +; CHECK: bb2: +; CHECK-NEXT: unreachable +; CHECK: bb3: +; CHECK-NEXT: br label [[BB4]] +; CHECK: bb4: +; CHECK-NEXT: call void @use_bool(i1 true) +; CHECK-NEXT: br label [[BB5:%.*]] +; CHECK: bb5: +; CHECK-NEXT: call void @use_ptr(ptr [[P1]]) +; CHECK-NEXT: br label [[BB5]] +; +entry: + %p2 = load ptr, ptr poison, align 8 + %cmp1 = icmp eq ptr %p2, %p1 + br i1 %cmp1, label %bb4, label %bb1 + +bb1: + switch i8 poison, label %bb2 [ + i8 0, label %bb1 + i8 1, label %bb3 + ] + +bb2: + unreachable + +bb3: + br label %bb4 + +bb4: + %phi1 = phi ptr [ %p2, %entry ], [ poison, %bb3 ] + %cmp2 = icmp eq ptr %phi1, %p1 + call void @use_bool(i1 %cmp2) + br label %bb5 + +bb5: + %phi2 = phi ptr [ poison, %bb5 ], [ %phi1, %bb4 ] + call void @use_ptr(ptr %phi2) + br label %bb5 +} + +define void @multiple_phi2(ptr %p1) { +; CHECK-LABEL: @multiple_phi2( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr poison, align 8 +; CHECK-NEXT: [[CMP1:%.*]] = icmp eq ptr [[P2]], [[P1:%.*]] +; CHECK-NEXT: br i1 [[CMP1]], label [[BB4:%.*]], label [[BB1:%.*]] +; CHECK: bb1: +; CHECK-NEXT: switch i8 poison, label [[BB2:%.*]] [ +; CHECK-NEXT: i8 0, label [[BB1]] +; CHECK-NEXT: i8 1, label [[BB3:%.*]] +; CHECK-NEXT: ] +; CHECK: bb2: +; CHECK-NEXT: br label [[BB4]] +; CHECK: bb3: +; CHECK-NEXT: br label [[BB4]] +; CHECK: bb4: +; CHECK-NEXT: [[PHI1:%.*]] = phi ptr [ [[P1]], [[ENTRY:%.*]] ], [ [[P2]], [[BB2]] ], [ poison, [[BB3]] ] +; CHECK-NEXT: [[CMP2:%.*]] = icmp eq ptr [[PHI1]], [[P1]] +; CHECK-NEXT: call void @use_bool(i1 [[CMP2]]) +; CHECK-NEXT: br label [[BB5:%.*]] +; CHECK: bb5: +; CHECK-NEXT: call void @use_ptr(ptr [[PHI1]]) +; CHECK-NEXT: br label [[BB5]] +; +entry: + %p2 = load ptr, ptr poison, align 8 + %cmp1 = icmp eq ptr %p2, %p1 + br i1 %cmp1, label %bb4, label %bb1 + +bb1: + switch i8 poison, label %bb2 [ + i8 0, label %bb1 + i8 1, label %bb3 + ] + +bb2: + br label %bb4 + +bb3: + br label %bb4 + +bb4: + %phi1 = phi ptr [ %p2, %entry ], [ %p2, %bb2 ], [ poison, %bb3 ] + %cmp2 = icmp eq ptr %phi1, %p1 + call void @use_bool(i1 %cmp2) + br label %bb5 + +bb5: + %phi2 = phi ptr [ poison, %bb5 ], [ %phi1, %bb4 ] + call void @use_ptr(ptr %phi2) + br label %bb5 +} + +declare void @use_bool(i1) +declare void @use_ptr(ptr)