1; RUN: opt < %s -passes=jump-threading -S | FileCheck %s 2 3target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" 4target triple = "i386-apple-darwin7" 5 6declare void @use(ptr) 7 8; Check that we propagate nonnull to dominated loads, when we find an available 9; loaded value. 10; CHECK-LABEL: @test1( 11; CHECK-LABEL: ret1: 12; CHECK-NEXT: %[[p1:.*]] = load ptr, ptr %ptr 13; CHECK-NOT: !nonnull 14; CHECK-NEXT: store i32 1, ptr %[[p1]] 15; CHECK-NEXT: tail call void @use(ptr null) 16; CHECK-NEXT: ret void 17 18; CHECK-LABEL: ret2: 19; CHECK-NEXT: %[[p2:.*]] = load ptr, ptr %ptr, align 4, !nonnull !0 20; CHECK: tail call void @use(ptr %[[p2]]) 21; CHECK-NEXT: ret void 22define void @test1(ptr %ptr, i1 %c) { 23 br i1 %c, label %d1, label %d2 24 25d1: 26 %p1 = load ptr, ptr %ptr, !nonnull !0 27 br label %d3 28 29d2: 30 br label %d3 31 32d3: 33 %pm = phi ptr [ null, %d2 ], [ %p1, %d1 ] 34 %p2 = load ptr, ptr %ptr 35 store i32 1, ptr %p2 36 %c2 = icmp eq ptr %pm, null 37 br i1 %c2, label %ret1, label %ret2 38 39ret1: 40 tail call void @use(ptr %pm) nounwind 41 ret void 42 43ret2: 44 tail call void @use(ptr %pm) nounwind 45 ret void 46} 47 48; Check that we propagate nonnull to dominated loads, when we find an available 49; loaded value. 50; CHECK-LABEL: @test2( 51; CHECK-LABEL: d3.thread: 52; CHECK-NEXT: %[[p1:.*]] = load ptr, ptr %ptr, align 4, !nonnull !0 53; CHECK-NEXT: store i32 1, ptr %[[p1]] 54; CHECK-NEXT: br label %ret1 55 56; CHECK-LABEL: d3: 57; CHECK-NEXT: %[[p_cmp:.*]] = load ptr, ptr %ptr 58; CHECK-NEXT: %[[p2:.*]] = load ptr, ptr %ptr, align 4, !nonnull !0 59; CHECK-NEXT: store i32 1, ptr %[[p2]] 60; CHECK-NEXT: icmp eq ptr %[[p_cmp]], null 61define void @test2(ptr %ptr, i1 %c) { 62 br i1 %c, label %d1, label %d2 63 64d1: 65 %p1 = load ptr, ptr %ptr 66 br label %d3 67 68d2: 69 br label %d3 70 71d3: 72 %pm = phi ptr [ null, %d2 ], [ %p1, %d1 ] 73 %p2 = load ptr, ptr %ptr, !nonnull !0 74 store i32 1, ptr %p2 75 %c2 = icmp eq ptr %pm, null 76 br i1 %c2, label %ret1, label %ret2 77 78ret1: 79 tail call void @use(ptr %pm) nounwind 80 ret void 81 82ret2: 83 tail call void @use(ptr %pm) nounwind 84 ret void 85} 86 87; Check that we do not propagate nonnull to loads predecessors that are combined 88; to a PHI node. 89; CHECK-LABEL: @test3( 90; CHECK-LABEL: d1: 91; CHECK-NEXT: %[[p1:.*]] = load ptr, ptr %ptr 92; CHECK-NOT: !nonnull 93 94; CHECK-LABEL: d2: 95; CHECK-NEXT: %[[p2:.*]] = load ptr, ptr %ptr 96; CHECK-NOT: !nonnull 97 98; CHECK-LABEL: d3: 99; CHECK-NEXT: phi ptr [ %[[p2]], %d2 ], [ %[[p1]], %d1 ] 100define void @test3(ptr %ptr) { 101d1: 102 %x = load ptr, ptr %ptr, !nonnull !0 103 br label %d3 104 105d2: 106 br label %d3 107 108d3: 109 %y = load ptr, ptr %ptr 110 store i32 1, ptr %y 111 %c2 = icmp eq ptr %y, @p 112 br i1 %c2, label %ret1, label %ret2 113 114ret1: 115 ret void 116 117ret2: 118 ret void 119} 120 121@p = external global i32 122 123!0 = !{} 124