1*0ddd5376SMax Kazantsev; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2cee313d2SEric Christopher; RUN: opt < %s -jump-threading -S | FileCheck %s 3cee313d2SEric Christopher; RUN: opt < %s -aa-pipeline=basic-aa -passes=jump-threading -S | FileCheck %s 4cee313d2SEric Christopher 5cee313d2SEric Christophertarget 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" 6cee313d2SEric Christophertarget triple = "i386-apple-darwin7" 7cee313d2SEric Christopher 8cee313d2SEric Christopher; Test that we can thread through the block with the partially redundant load (%2). 9cee313d2SEric Christopher; rdar://6402033 10cee313d2SEric Christopherdefine i32 @test1(i32* %P) nounwind { 11cee313d2SEric Christopher; CHECK-LABEL: @test1( 12*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 13*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 (...) @f1() #[[ATTR0:[0-9]+]] 14*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0 15*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[TMP1]], label [[BB1:%.*]], label [[BB1_THREAD:%.*]] 16*0ddd5376SMax Kazantsev; CHECK: bb1.thread: 17*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 42, i32* [[P:%.*]], align 4 18*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[BB3:%.*]] 19*0ddd5376SMax Kazantsev; CHECK: bb1: 20*0ddd5376SMax Kazantsev; CHECK-NEXT: [[DOTPR:%.*]] = load i32, i32* [[P]], align 4 21*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTPR]], 36 22*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[TMP2]], label [[BB3]], label [[BB2:%.*]] 23*0ddd5376SMax Kazantsev; CHECK: bb2: 24*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 (...) @f2() #[[ATTR0]] 25*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 0 26*0ddd5376SMax Kazantsev; CHECK: bb3: 27*0ddd5376SMax Kazantsev; CHECK-NEXT: [[RES_02:%.*]] = phi i32 [ 1, [[BB1_THREAD]] ], [ 0, [[BB1]] ] 28*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_02]] 29*0ddd5376SMax Kazantsev; 30cee313d2SEric Christopherentry: 31cee313d2SEric Christopher %0 = tail call i32 (...) @f1() nounwind ; <i32> [#uses=1] 32cee313d2SEric Christopher %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1] 33cee313d2SEric Christopher br i1 %1, label %bb1, label %bb 34cee313d2SEric Christopher 35cee313d2SEric Christopherbb: ; preds = %entry 36cee313d2SEric Christopher store i32 42, i32* %P, align 4 37cee313d2SEric Christopher br label %bb1 38cee313d2SEric Christopher 39cee313d2SEric Christopherbb1: ; preds = %entry, %bb 40cee313d2SEric Christopher %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ] ; <i32> [#uses=2] 41cee313d2SEric Christopher %2 = load i32, i32* %P, align 4 ; <i32> [#uses=1] 42cee313d2SEric Christopher %3 = icmp sgt i32 %2, 36 ; <i1> [#uses=1] 43cee313d2SEric Christopher br i1 %3, label %bb3, label %bb2 44cee313d2SEric Christopher 45cee313d2SEric Christopherbb2: ; preds = %bb1 46cee313d2SEric Christopher %4 = tail call i32 (...) @f2() nounwind ; <i32> [#uses=0] 47cee313d2SEric Christopher ret i32 %res.0 48cee313d2SEric Christopher 49cee313d2SEric Christopherbb3: ; preds = %bb1 50cee313d2SEric Christopher ret i32 %res.0 51cee313d2SEric Christopher} 52cee313d2SEric Christopher 53cee313d2SEric Christopherdeclare i32 @f1(...) 54cee313d2SEric Christopher 55cee313d2SEric Christopherdeclare i32 @f2(...) 56cee313d2SEric Christopher 57cee313d2SEric Christopher 58cee313d2SEric Christopher;; Check that we preserve TBAA information. 59cee313d2SEric Christopher; rdar://11039258 60cee313d2SEric Christopher 61cee313d2SEric Christopherdefine i32 @test2(i32* %P) nounwind { 62cee313d2SEric Christopher; CHECK-LABEL: @test2( 63*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 64*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 (...) @f1() #[[ATTR0]] 65*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0 66*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[TMP1]], label [[BB1:%.*]], label [[BB1_THREAD:%.*]] 67*0ddd5376SMax Kazantsev; CHECK: bb1.thread: 68*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 42, i32* [[P:%.*]], align 4, !tbaa [[TBAA0:![0-9]+]] 69*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[BB3:%.*]] 70*0ddd5376SMax Kazantsev; CHECK: bb1: 71*0ddd5376SMax Kazantsev; CHECK-NEXT: [[DOTPR:%.*]] = load i32, i32* [[P]], align 4, !tbaa [[TBAA0]] 72*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOTPR]], 36 73*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[TMP2]], label [[BB3]], label [[BB2:%.*]] 74*0ddd5376SMax Kazantsev; CHECK: bb2: 75*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP3:%.*]] = tail call i32 (...) @f2() #[[ATTR0]] 76*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 0 77*0ddd5376SMax Kazantsev; CHECK: bb3: 78*0ddd5376SMax Kazantsev; CHECK-NEXT: [[RES_02:%.*]] = phi i32 [ 1, [[BB1_THREAD]] ], [ 0, [[BB1]] ] 79*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_02]] 80*0ddd5376SMax Kazantsev; 81cee313d2SEric Christopherentry: 82cee313d2SEric Christopher %0 = tail call i32 (...) @f1() nounwind ; <i32> [#uses=1] 83cee313d2SEric Christopher %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1] 84cee313d2SEric Christopher br i1 %1, label %bb1, label %bb 85cee313d2SEric Christopher 86cee313d2SEric Christopherbb: ; preds = %entry 87cee313d2SEric Christopher store i32 42, i32* %P, align 4, !tbaa !0 88cee313d2SEric Christopher br label %bb1 89cee313d2SEric Christopher 90cee313d2SEric Christopherbb1: ; preds = %entry, %bb 91cee313d2SEric Christopher %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ] 92cee313d2SEric Christopher %2 = load i32, i32* %P, align 4, !tbaa !0 93cee313d2SEric Christopher %3 = icmp sgt i32 %2, 36 94cee313d2SEric Christopher br i1 %3, label %bb3, label %bb2 95cee313d2SEric Christopher 96cee313d2SEric Christopherbb2: ; preds = %bb1 97cee313d2SEric Christopher %4 = tail call i32 (...) @f2() nounwind 98cee313d2SEric Christopher ret i32 %res.0 99cee313d2SEric Christopher 100cee313d2SEric Christopherbb3: ; preds = %bb1 101cee313d2SEric Christopher ret i32 %res.0 102cee313d2SEric Christopher} 103cee313d2SEric Christopher 104cee313d2SEric Christopherdefine i32 @test3(i8** %x, i1 %f) { 105cee313d2SEric Christopher; Correctly thread loads of different (but compatible) types, placing bitcasts 106cee313d2SEric Christopher; as necessary in the predecessors. This is especially tricky because the same 107cee313d2SEric Christopher; predecessor ends up with two entries in the PHI node and they must share 108cee313d2SEric Christopher; a single cast. 109cee313d2SEric Christopher; CHECK-LABEL: @test3( 110*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 111*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP0:%.*]] = bitcast i8** [[X:%.*]] to i32** 112*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP1:%.*]] = load i32*, i32** [[TMP0]], align 8 113*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32* [[TMP1]] to i8* 114*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[F:%.*]], label [[IF_END57:%.*]], label [[IF_END57]] 115*0ddd5376SMax Kazantsev; CHECK: if.end57: 116*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TMP3:%.*]] = phi i8* [ [[TMP2]], [[ENTRY:%.*]] ], [ [[TMP2]], [[ENTRY]] ] 117*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TOBOOL59:%.*]] = icmp eq i8* [[TMP3]], null 118*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[TOBOOL59]], label [[RETURN:%.*]], label [[IF_THEN60:%.*]] 119*0ddd5376SMax Kazantsev; CHECK: if.then60: 120*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 42 121*0ddd5376SMax Kazantsev; CHECK: return: 122*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 13 123*0ddd5376SMax Kazantsev; 124cee313d2SEric Christopherentry: 125cee313d2SEric Christopher %0 = bitcast i8** %x to i32** 126cee313d2SEric Christopher %1 = load i32*, i32** %0, align 8 127cee313d2SEric Christopher br i1 %f, label %if.end57, label %if.then56 128cee313d2SEric Christopher 129cee313d2SEric Christopherif.then56: 130cee313d2SEric Christopher br label %if.end57 131cee313d2SEric Christopher 132cee313d2SEric Christopherif.end57: 133cee313d2SEric Christopher %2 = load i8*, i8** %x, align 8 134cee313d2SEric Christopher %tobool59 = icmp eq i8* %2, null 135cee313d2SEric Christopher br i1 %tobool59, label %return, label %if.then60 136cee313d2SEric Christopher 137cee313d2SEric Christopherif.then60: 138cee313d2SEric Christopher ret i32 42 139cee313d2SEric Christopher 140cee313d2SEric Christopherreturn: 141cee313d2SEric Christopher ret i32 13 142cee313d2SEric Christopher} 143cee313d2SEric Christopher 144cee313d2SEric Christopherdefine i32 @test4(i32* %P) { 145cee313d2SEric Christopher; CHECK-LABEL: @test4( 146*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 147*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V0:%.*]] = tail call i32 (...) @f1() 148*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V1:%.*]] = icmp eq i32 [[V0]], 0 149*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[V1]], label [[BB1:%.*]], label [[BB1_THREAD:%.*]] 150*0ddd5376SMax Kazantsev; CHECK: bb1.thread: 151*0ddd5376SMax Kazantsev; CHECK-NEXT: store atomic i32 42, i32* [[P:%.*]] unordered, align 4 152*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[BB3:%.*]] 153*0ddd5376SMax Kazantsev; CHECK: bb1: 154*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V2_PR:%.*]] = load atomic i32, i32* [[P]] unordered, align 4 155*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V3:%.*]] = icmp sgt i32 [[V2_PR]], 36 156*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[V3]], label [[BB3]], label [[BB2:%.*]] 157*0ddd5376SMax Kazantsev; CHECK: bb2: 158*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V4:%.*]] = tail call i32 (...) @f2() 159*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 0 160*0ddd5376SMax Kazantsev; CHECK: bb3: 161*0ddd5376SMax Kazantsev; CHECK-NEXT: [[RES_04:%.*]] = phi i32 [ 1, [[BB1_THREAD]] ], [ 0, [[BB1]] ] 162*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_04]] 163*0ddd5376SMax Kazantsev; 164cee313d2SEric Christopherentry: 165cee313d2SEric Christopher %v0 = tail call i32 (...) @f1() 166cee313d2SEric Christopher %v1 = icmp eq i32 %v0, 0 167cee313d2SEric Christopher br i1 %v1, label %bb1, label %bb 168cee313d2SEric Christopher 169cee313d2SEric Christopherbb: 170cee313d2SEric Christopher store atomic i32 42, i32* %P unordered, align 4 171cee313d2SEric Christopher br label %bb1 172cee313d2SEric Christopher 173cee313d2SEric Christopherbb1: 174cee313d2SEric Christopher %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ] 175cee313d2SEric Christopher %v2 = load atomic i32, i32* %P unordered, align 4 176cee313d2SEric Christopher %v3 = icmp sgt i32 %v2, 36 177cee313d2SEric Christopher br i1 %v3, label %bb3, label %bb2 178cee313d2SEric Christopher 179cee313d2SEric Christopherbb2: 180cee313d2SEric Christopher %v4 = tail call i32 (...) @f2() 181cee313d2SEric Christopher ret i32 %res.0 182cee313d2SEric Christopher 183cee313d2SEric Christopherbb3: 184cee313d2SEric Christopher ret i32 %res.0 185cee313d2SEric Christopher} 186cee313d2SEric Christopher 187cee313d2SEric Christopherdefine i32 @test5(i32* %P) { 188cee313d2SEric Christopher; Negative test 189cee313d2SEric Christopher; CHECK-LABEL: @test5( 190*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 191*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V0:%.*]] = tail call i32 (...) @f1() 192*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V1:%.*]] = icmp eq i32 [[V0]], 0 193*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[V1]], label [[BB1:%.*]], label [[BB:%.*]] 194*0ddd5376SMax Kazantsev; CHECK: bb: 195*0ddd5376SMax Kazantsev; CHECK-NEXT: store atomic i32 42, i32* [[P:%.*]] release, align 4 196*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[BB1]] 197*0ddd5376SMax Kazantsev; CHECK: bb1: 198*0ddd5376SMax Kazantsev; CHECK-NEXT: [[RES_0:%.*]] = phi i32 [ 1, [[BB]] ], [ 0, [[ENTRY:%.*]] ] 199*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V2:%.*]] = load atomic i32, i32* [[P]] acquire, align 4 200*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V3:%.*]] = icmp sgt i32 [[V2]], 36 201*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[V3]], label [[BB3:%.*]], label [[BB2:%.*]] 202*0ddd5376SMax Kazantsev; CHECK: bb2: 203*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V4:%.*]] = tail call i32 (...) @f2() 204*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_0]] 205*0ddd5376SMax Kazantsev; CHECK: bb3: 206*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_0]] 207*0ddd5376SMax Kazantsev; 208cee313d2SEric Christopherentry: 209cee313d2SEric Christopher %v0 = tail call i32 (...) @f1() 210cee313d2SEric Christopher %v1 = icmp eq i32 %v0, 0 211cee313d2SEric Christopher br i1 %v1, label %bb1, label %bb 212cee313d2SEric Christopher 213cee313d2SEric Christopherbb: 214cee313d2SEric Christopher store atomic i32 42, i32* %P release, align 4 215cee313d2SEric Christopher br label %bb1 216cee313d2SEric Christopher 217cee313d2SEric Christopherbb1: 218cee313d2SEric Christopher 219cee313d2SEric Christopher %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ] 220cee313d2SEric Christopher %v2 = load atomic i32, i32* %P acquire, align 4 221cee313d2SEric Christopher %v3 = icmp sgt i32 %v2, 36 222cee313d2SEric Christopher br i1 %v3, label %bb3, label %bb2 223cee313d2SEric Christopher 224cee313d2SEric Christopherbb2: 225cee313d2SEric Christopher %v4 = tail call i32 (...) @f2() 226cee313d2SEric Christopher ret i32 %res.0 227cee313d2SEric Christopher 228cee313d2SEric Christopherbb3: 229cee313d2SEric Christopher ret i32 %res.0 230cee313d2SEric Christopher} 231cee313d2SEric Christopher 232cee313d2SEric Christopherdefine i32 @test6(i32* %P) { 233cee313d2SEric Christopher; Negative test 234cee313d2SEric Christopher; CHECK-LABEL: @test6( 235*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 236*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V0:%.*]] = tail call i32 (...) @f1() 237*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V1:%.*]] = icmp eq i32 [[V0]], 0 238*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[V1]], label [[BB1:%.*]], label [[BB:%.*]] 239*0ddd5376SMax Kazantsev; CHECK: bb: 240*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 42, i32* [[P:%.*]], align 4 241*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[BB1]] 242*0ddd5376SMax Kazantsev; CHECK: bb1: 243*0ddd5376SMax Kazantsev; CHECK-NEXT: [[RES_0:%.*]] = phi i32 [ 1, [[BB]] ], [ 0, [[ENTRY:%.*]] ] 244*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V2:%.*]] = load atomic i32, i32* [[P]] acquire, align 4 245*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V3:%.*]] = icmp sgt i32 [[V2]], 36 246*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[V3]], label [[BB3:%.*]], label [[BB2:%.*]] 247*0ddd5376SMax Kazantsev; CHECK: bb2: 248*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V4:%.*]] = tail call i32 (...) @f2() 249*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_0]] 250*0ddd5376SMax Kazantsev; CHECK: bb3: 251*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_0]] 252*0ddd5376SMax Kazantsev; 253cee313d2SEric Christopherentry: 254cee313d2SEric Christopher %v0 = tail call i32 (...) @f1() 255cee313d2SEric Christopher %v1 = icmp eq i32 %v0, 0 256cee313d2SEric Christopher br i1 %v1, label %bb1, label %bb 257cee313d2SEric Christopher 258cee313d2SEric Christopherbb: 259cee313d2SEric Christopher store i32 42, i32* %P 260cee313d2SEric Christopher br label %bb1 261cee313d2SEric Christopher 262cee313d2SEric Christopherbb1: 263cee313d2SEric Christopher 264cee313d2SEric Christopher %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ] 265cee313d2SEric Christopher %v2 = load atomic i32, i32* %P acquire, align 4 266cee313d2SEric Christopher %v3 = icmp sgt i32 %v2, 36 267cee313d2SEric Christopher br i1 %v3, label %bb3, label %bb2 268cee313d2SEric Christopher 269cee313d2SEric Christopherbb2: 270cee313d2SEric Christopher %v4 = tail call i32 (...) @f2() 271cee313d2SEric Christopher ret i32 %res.0 272cee313d2SEric Christopher 273cee313d2SEric Christopherbb3: 274cee313d2SEric Christopher ret i32 %res.0 275cee313d2SEric Christopher} 276cee313d2SEric Christopher 277cee313d2SEric Christopherdefine i32 @test7(i32* %P) { 278cee313d2SEric Christopher; Negative test 279cee313d2SEric Christopher; CHECK-LABEL: @test7( 280*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 281*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V0:%.*]] = tail call i32 (...) @f1() 282*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V1:%.*]] = icmp eq i32 [[V0]], 0 283*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[V1]], label [[BB1:%.*]], label [[BB:%.*]] 284*0ddd5376SMax Kazantsev; CHECK: bb: 285*0ddd5376SMax Kazantsev; CHECK-NEXT: [[VAL:%.*]] = load i32, i32* [[P:%.*]], align 4 286*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[BB1]] 287*0ddd5376SMax Kazantsev; CHECK: bb1: 288*0ddd5376SMax Kazantsev; CHECK-NEXT: [[RES_0:%.*]] = phi i32 [ 1, [[BB]] ], [ 0, [[ENTRY:%.*]] ] 289*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V2:%.*]] = load atomic i32, i32* [[P]] acquire, align 4 290*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V3:%.*]] = icmp sgt i32 [[V2]], 36 291*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[V3]], label [[BB3:%.*]], label [[BB2:%.*]] 292*0ddd5376SMax Kazantsev; CHECK: bb2: 293*0ddd5376SMax Kazantsev; CHECK-NEXT: [[V4:%.*]] = tail call i32 (...) @f2() 294*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_0]] 295*0ddd5376SMax Kazantsev; CHECK: bb3: 296*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 [[RES_0]] 297*0ddd5376SMax Kazantsev; 298cee313d2SEric Christopherentry: 299cee313d2SEric Christopher %v0 = tail call i32 (...) @f1() 300cee313d2SEric Christopher %v1 = icmp eq i32 %v0, 0 301cee313d2SEric Christopher br i1 %v1, label %bb1, label %bb 302cee313d2SEric Christopher 303cee313d2SEric Christopherbb: 304cee313d2SEric Christopher %val = load i32, i32* %P 305cee313d2SEric Christopher br label %bb1 306cee313d2SEric Christopher 307cee313d2SEric Christopherbb1: 308cee313d2SEric Christopher 309cee313d2SEric Christopher %res.0 = phi i32 [ 1, %bb ], [ 0, %entry ] 310cee313d2SEric Christopher %v2 = load atomic i32, i32* %P acquire, align 4 311cee313d2SEric Christopher %v3 = icmp sgt i32 %v2, 36 312cee313d2SEric Christopher br i1 %v3, label %bb3, label %bb2 313cee313d2SEric Christopher 314cee313d2SEric Christopherbb2: 315cee313d2SEric Christopher %v4 = tail call i32 (...) @f2() 316cee313d2SEric Christopher ret i32 %res.0 317cee313d2SEric Christopher 318cee313d2SEric Christopherbb3: 319cee313d2SEric Christopher ret i32 %res.0 320cee313d2SEric Christopher} 321cee313d2SEric Christopher 322cee313d2SEric Christopher; Make sure we merge the aliasing metadata. We keep the range metadata for the 323cee313d2SEric Christopher; first load, as it dominates the second load. Hence we can eliminate the 324cee313d2SEric Christopher; branch. 325cee313d2SEric Christopherdefine void @test8(i32*, i32*, i32*) { 326cee313d2SEric Christopher; CHECK-LABEL: @test8( 327*0ddd5376SMax Kazantsev; CHECK-NEXT: ret2: 328*0ddd5376SMax Kazantsev; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[TMP0:%.*]], align 4, !range [[RNG4:![0-9]+]] 329*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 [[A]], i32* [[TMP1:%.*]], align 4 330*0ddd5376SMax Kazantsev; CHECK-NEXT: [[XXX:%.*]] = tail call i32 (...) @f1() #[[ATTR0]] 331cee313d2SEric Christopher; CHECK-NEXT: ret void 332*0ddd5376SMax Kazantsev; 333cee313d2SEric Christopher %a = load i32, i32* %0, !tbaa !0, !range !4, !alias.scope !9, !noalias !10 334cee313d2SEric Christopher %b = load i32, i32* %0, !range !5 335cee313d2SEric Christopher store i32 %a, i32* %1 336cee313d2SEric Christopher %c = icmp eq i32 %b, 8 337cee313d2SEric Christopher br i1 %c, label %ret1, label %ret2 338cee313d2SEric Christopher 339cee313d2SEric Christopherret1: 340cee313d2SEric Christopher ret void 341cee313d2SEric Christopher 342cee313d2SEric Christopherret2: 343cee313d2SEric Christopher %xxx = tail call i32 (...) @f1() nounwind 344cee313d2SEric Christopher ret void 345cee313d2SEric Christopher} 346cee313d2SEric Christopher 347cee313d2SEric Christopher; Make sure we merge/PRE aliasing metadata correctly. That means that 348cee313d2SEric Christopher; we need to remove metadata from the existing load, and add appropriate 349cee313d2SEric Christopher; metadata to the newly inserted load. 350cee313d2SEric Christopherdefine void @test9(i32*, i32*, i32*, i1 %c) { 351cee313d2SEric Christopher; CHECK-LABEL: @test9( 352*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C:%.*]], label [[D1:%.*]], label [[D2:%.*]] 353*0ddd5376SMax Kazantsev; CHECK: d1: 354*0ddd5376SMax Kazantsev; CHECK-NEXT: [[A:%.*]] = load i32, i32* [[TMP0:%.*]], align 4 355*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[D3:%.*]] 356*0ddd5376SMax Kazantsev; CHECK: d2: 357*0ddd5376SMax Kazantsev; CHECK-NEXT: [[XXXX:%.*]] = tail call i32 (...) @f1() #[[ATTR0]] 358*0ddd5376SMax Kazantsev; CHECK-NEXT: [[B_PR:%.*]] = load i32, i32* [[TMP0]], align 4, !tbaa [[TBAA0]] 359*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[D3]] 360*0ddd5376SMax Kazantsev; CHECK: d3: 361*0ddd5376SMax Kazantsev; CHECK-NEXT: [[B:%.*]] = phi i32 [ [[B_PR]], [[D2]] ], [ [[A]], [[D1]] ] 362*0ddd5376SMax Kazantsev; CHECK-NEXT: [[P:%.*]] = phi i32 [ 1, [[D2]] ], [ [[A]], [[D1]] ] 363*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 [[P]], i32* [[TMP1:%.*]], align 4 364*0ddd5376SMax Kazantsev; CHECK-NEXT: [[C2:%.*]] = icmp eq i32 [[B]], 8 365*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C2]], label [[RET1:%.*]], label [[RET2:%.*]] 366*0ddd5376SMax Kazantsev; CHECK: ret1: 367*0ddd5376SMax Kazantsev; CHECK-NEXT: ret void 368*0ddd5376SMax Kazantsev; CHECK: ret2: 369*0ddd5376SMax Kazantsev; CHECK-NEXT: [[XXX:%.*]] = tail call i32 (...) @f1() #[[ATTR0]] 370*0ddd5376SMax Kazantsev; CHECK-NEXT: ret void 371*0ddd5376SMax Kazantsev; 372cee313d2SEric Christopher br i1 %c, label %d1, label %d2 373cee313d2SEric Christopher 374cee313d2SEric Christopherd1: 375cee313d2SEric Christopher %a = load i32, i32* %0, !range !4, !alias.scope !9, !noalias !10 376cee313d2SEric Christopher br label %d3 377cee313d2SEric Christopher 378cee313d2SEric Christopherd2: 379cee313d2SEric Christopher %xxxx = tail call i32 (...) @f1() nounwind 380cee313d2SEric Christopher br label %d3 381cee313d2SEric Christopher 382cee313d2SEric Christopherd3: 383cee313d2SEric Christopher %p = phi i32 [ 1, %d2 ], [ %a, %d1 ] 384cee313d2SEric Christopher %b = load i32, i32* %0, !tbaa !0 385cee313d2SEric Christopher store i32 %p, i32* %1 386cee313d2SEric Christopher %c2 = icmp eq i32 %b, 8 387cee313d2SEric Christopher br i1 %c2, label %ret1, label %ret2 388cee313d2SEric Christopher 389cee313d2SEric Christopherret1: 390cee313d2SEric Christopher ret void 391cee313d2SEric Christopher 392cee313d2SEric Christopherret2: 393cee313d2SEric Christopher %xxx = tail call i32 (...) @f1() nounwind 394cee313d2SEric Christopher ret void 395cee313d2SEric Christopher} 396cee313d2SEric Christopher 397cee313d2SEric Christopherdefine i32 @fn_noalias(i1 %c2,i64* noalias %P, i64* noalias %P2) { 398*0ddd5376SMax Kazantsev; CHECK-LABEL: @fn_noalias( 399*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 400*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C2:%.*]], label [[COND2:%.*]], label [[COND1:%.*]] 401*0ddd5376SMax Kazantsev; CHECK: cond1: 402*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L1:%.*]] = load i64, i64* [[P:%.*]], align 4 403*0ddd5376SMax Kazantsev; CHECK-NEXT: store i64 42, i64* [[P2:%.*]], align 4 404*0ddd5376SMax Kazantsev; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[L1]], 0 405*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C]], label [[COND2_THREAD:%.*]], label [[END:%.*]] 406*0ddd5376SMax Kazantsev; CHECK: cond2.thread: 407*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn2(i64 [[L1]]) 408*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[COND3:%.*]] 409*0ddd5376SMax Kazantsev; CHECK: cond2: 410*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L2_PR:%.*]] = load i64, i64* [[P]], align 4 411*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn2(i64 [[L2_PR]]) 412*0ddd5376SMax Kazantsev; CHECK-NEXT: [[C3:%.*]] = icmp eq i64 [[L2_PR]], 0 413*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C3]], label [[COND3]], label [[END]] 414*0ddd5376SMax Kazantsev; CHECK: cond3: 415*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L23:%.*]] = phi i64 [ [[L1]], [[COND2_THREAD]] ], [ [[L2_PR]], [[COND2]] ] 416*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn3(i64 [[L23]]) 417*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[END]] 418*0ddd5376SMax Kazantsev; CHECK: end: 419*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 0 420*0ddd5376SMax Kazantsev; 421cee313d2SEric Christopherentry: 422cee313d2SEric Christopher br i1 %c2, label %cond2, label %cond1 423cee313d2SEric Christopher 424cee313d2SEric Christophercond1: 425cee313d2SEric Christopher %l1 = load i64, i64* %P 426cee313d2SEric Christopher store i64 42, i64* %P2 427cee313d2SEric Christopher %c = icmp eq i64 %l1, 0 428cee313d2SEric Christopher br i1 %c, label %cond2, label %end 429cee313d2SEric Christopher 430cee313d2SEric Christophercond2: 431cee313d2SEric Christopher %l2 = load i64, i64* %P 432cee313d2SEric Christopher call void @fn2(i64 %l2) 433cee313d2SEric Christopher %c3 = icmp eq i64 %l2, 0 434cee313d2SEric Christopher br i1 %c3, label %cond3, label %end 435cee313d2SEric Christopher 436cee313d2SEric Christophercond3: 437cee313d2SEric Christopher call void @fn3(i64 %l2) 438cee313d2SEric Christopher br label %end 439cee313d2SEric Christopher 440cee313d2SEric Christopherend: 441cee313d2SEric Christopher ret i32 0 442cee313d2SEric Christopher} 443cee313d2SEric Christopher 444cee313d2SEric Christopher; This tests if we can thread from %sw.bb.i to %do.body.preheader.i67 through 445cee313d2SEric Christopher; %sw.bb21.i. To make this happen, %l2 should be detected as a partically 446cee313d2SEric Christopher; redundant load with %l3 across the store to %phase in %sw.bb21.i. 447cee313d2SEric Christopher 448cee313d2SEric Christopher%struct.NEXT_MOVE = type { i32, i32, i32* } 449cee313d2SEric Christopher@hash_move = unnamed_addr global [65 x i32] zeroinitializer, align 4 450cee313d2SEric Christopher@current_move = internal global [65 x i32] zeroinitializer, align 4 451cee313d2SEric Christopher@last = internal unnamed_addr global [65 x i32*] zeroinitializer, align 8 452cee313d2SEric Christopher@next_status = internal unnamed_addr global [65 x %struct.NEXT_MOVE] zeroinitializer, align 8 453cee313d2SEric Christopherdefine fastcc i32 @Search(i64 %idxprom.i, i64 %idxprom.i89, i32 %c) { 454*0ddd5376SMax Kazantsev; CHECK-LABEL: @Search( 455*0ddd5376SMax Kazantsev; CHECK-NEXT: cond.true282: 456*0ddd5376SMax Kazantsev; CHECK-NEXT: [[ARRAYIDX185:%.*]] = getelementptr inbounds [65 x i32], [65 x i32]* @hash_move, i64 0, i64 [[IDXPROM_I:%.*]] 457*0ddd5376SMax Kazantsev; CHECK-NEXT: [[ARRAYIDX307:%.*]] = getelementptr inbounds [65 x i32], [65 x i32]* @current_move, i64 0, i64 [[IDXPROM_I]] 458*0ddd5376SMax Kazantsev; CHECK-NEXT: [[ARRAYIDX89:%.*]] = getelementptr inbounds [65 x i32*], [65 x i32*]* @last, i64 0, i64 [[IDXPROM_I]] 459*0ddd5376SMax Kazantsev; CHECK-NEXT: [[PHASE:%.*]] = getelementptr inbounds [65 x %struct.NEXT_MOVE], [65 x %struct.NEXT_MOVE]* @next_status, i64 0, i64 [[IDXPROM_I]], i32 0 460*0ddd5376SMax Kazantsev; CHECK-NEXT: switch i32 [[C:%.*]], label [[CLEANUP:%.*]] [ 461*0ddd5376SMax Kazantsev; CHECK-NEXT: i32 1, label [[SW_BB_I:%.*]] 462*0ddd5376SMax Kazantsev; CHECK-NEXT: i32 0, label [[SW_BB21_I:%.*]] 463*0ddd5376SMax Kazantsev; CHECK-NEXT: ] 464*0ddd5376SMax Kazantsev; CHECK: sw.bb.i: 465*0ddd5376SMax Kazantsev; CHECK-NEXT: [[CALL_I62:%.*]] = call fastcc i32* @GenerateCheckEvasions() 466*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32* [[CALL_I62]], i32** [[ARRAYIDX89]], align 8 467*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L2:%.*]] = load i32, i32* [[ARRAYIDX185]], align 4 468*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TOBOOL_I63:%.*]] = icmp eq i32 [[L2]], 0 469*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[TOBOOL_I63]], label [[SW_BB21_I_THREAD:%.*]], label [[IF_THEN_I64:%.*]] 470*0ddd5376SMax Kazantsev; CHECK: sw.bb21.i.thread: 471*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 10, i32* [[PHASE]], align 8 472*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[DO_BODY_PREHEADER_I67:%.*]] 473*0ddd5376SMax Kazantsev; CHECK: if.then.i64: 474*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 7, i32* [[PHASE]], align 8 475*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 [[L2]], i32* [[ARRAYIDX307]], align 4 476*0ddd5376SMax Kazantsev; CHECK-NEXT: [[CALL16_I:%.*]] = call fastcc i32 @ValidMove(i32 [[L2]]) 477*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TOBOOL17_I:%.*]] = icmp eq i32 [[CALL16_I]], 0 478*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[TOBOOL17_I]], label [[IF_ELSE_I65:%.*]], label [[CLEANUP]] 479*0ddd5376SMax Kazantsev; CHECK: if.else.i65: 480*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @f65() 481*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[SW_BB21_I]] 482*0ddd5376SMax Kazantsev; CHECK: sw.bb21.i: 483*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L3_PR:%.*]] = load i32, i32* [[ARRAYIDX185]], align 4 484*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 10, i32* [[PHASE]], align 8 485*0ddd5376SMax Kazantsev; CHECK-NEXT: [[TOBOOL27_I:%.*]] = icmp eq i32 [[L3_PR]], 0 486*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[TOBOOL27_I]], label [[DO_BODY_PREHEADER_I67]], label [[CLEANUP]] 487*0ddd5376SMax Kazantsev; CHECK: do.body.preheader.i67: 488*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @f67() 489*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 67 490*0ddd5376SMax Kazantsev; CHECK: cleanup: 491*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @Cleanup() 492*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 0 493*0ddd5376SMax Kazantsev; 494cee313d2SEric Christopherentry: 495cee313d2SEric Christopher %arrayidx185 = getelementptr inbounds [65 x i32], [65 x i32]* @hash_move, i64 0, i64 %idxprom.i 496cee313d2SEric Christopher %arrayidx307 = getelementptr inbounds [65 x i32], [65 x i32]* @current_move, i64 0, i64 %idxprom.i 497cee313d2SEric Christopher %arrayidx89 = getelementptr inbounds [65 x i32*], [65 x i32*]* @last, i64 0, i64 %idxprom.i 498cee313d2SEric Christopher %phase = getelementptr inbounds [65 x %struct.NEXT_MOVE], [65 x %struct.NEXT_MOVE]* @next_status, i64 0, i64 %idxprom.i, i32 0 499cee313d2SEric Christopher br label %cond.true282 500cee313d2SEric Christopher 501cee313d2SEric Christophercond.true282: 502cee313d2SEric Christopher switch i32 %c, label %sw.default.i [ 503cee313d2SEric Christopher i32 1, label %sw.bb.i 504cee313d2SEric Christopher i32 0, label %sw.bb21.i 505cee313d2SEric Christopher ] 506cee313d2SEric Christopher 507cee313d2SEric Christophersw.default.i: 508cee313d2SEric Christopher br label %cleanup 509cee313d2SEric Christopher 510cee313d2SEric Christophersw.bb.i: 511cee313d2SEric Christopher %call.i62 = call fastcc i32* @GenerateCheckEvasions() 512cee313d2SEric Christopher store i32* %call.i62, i32** %arrayidx89, align 8 513cee313d2SEric Christopher %l2 = load i32, i32* %arrayidx185, align 4 514cee313d2SEric Christopher %tobool.i63 = icmp eq i32 %l2, 0 515cee313d2SEric Christopher br i1 %tobool.i63, label %sw.bb21.i, label %if.then.i64 516cee313d2SEric Christopher 517cee313d2SEric Christopherif.then.i64: ; preds = %sw.bb.i 518cee313d2SEric Christopher store i32 7, i32* %phase, align 8 519cee313d2SEric Christopher store i32 %l2, i32* %arrayidx307, align 4 520cee313d2SEric Christopher %call16.i = call fastcc i32 @ValidMove(i32 %l2) 521cee313d2SEric Christopher %tobool17.i = icmp eq i32 %call16.i, 0 522cee313d2SEric Christopher br i1 %tobool17.i, label %if.else.i65, label %cleanup 523cee313d2SEric Christopher 524cee313d2SEric Christopherif.else.i65: 525cee313d2SEric Christopher call void @f65() 526cee313d2SEric Christopher br label %sw.bb21.i 527cee313d2SEric Christopher 528cee313d2SEric Christophersw.bb21.i: 529cee313d2SEric Christopher store i32 10, i32* %phase, align 8 530cee313d2SEric Christopher %l3= load i32, i32* %arrayidx185, align 4 531cee313d2SEric Christopher %tobool27.i = icmp eq i32 %l3, 0 532cee313d2SEric Christopher br i1 %tobool27.i, label %do.body.preheader.i67, label %cleanup 533cee313d2SEric Christopher 534cee313d2SEric Christopherdo.body.preheader.i67: 535cee313d2SEric Christopher call void @f67() 536cee313d2SEric Christopher ret i32 67 537cee313d2SEric Christopher 538cee313d2SEric Christophercleanup: 539cee313d2SEric Christopher call void @Cleanup() 540cee313d2SEric Christopher ret i32 0 541cee313d2SEric Christopher} 542cee313d2SEric Christopher 543cee313d2SEric Christopherdeclare fastcc i32* @GenerateCheckEvasions() 544cee313d2SEric Christopherdeclare fastcc i32 @ValidMove(i32 %move) 545cee313d2SEric Christopherdeclare void @f67() 546cee313d2SEric Christopherdeclare void @Cleanup() 547cee313d2SEric Christopherdeclare void @f65() 548cee313d2SEric Christopher 549cee313d2SEric Christopherdefine i32 @fn_SinglePred(i1 %c2,i64* %P) { 550*0ddd5376SMax Kazantsev; CHECK-LABEL: @fn_SinglePred( 551*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 552*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L1:%.*]] = load i64, i64* [[P:%.*]], align 4 553*0ddd5376SMax Kazantsev; CHECK-NEXT: [[C:%.*]] = icmp eq i64 [[L1]], 0 554*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C]], label [[COND3:%.*]], label [[COND1:%.*]] 555*0ddd5376SMax Kazantsev; CHECK: cond1: 556*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C2:%.*]], label [[COND2:%.*]], label [[END:%.*]] 557*0ddd5376SMax Kazantsev; CHECK: cond2: 558*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L2:%.*]] = phi i64 [ [[L1]], [[COND1]] ] 559*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn2(i64 [[L2]]) 560*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[END]] 561*0ddd5376SMax Kazantsev; CHECK: cond3: 562*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn2(i64 [[L1]]) 563*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn3(i64 [[L1]]) 564*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[END]] 565*0ddd5376SMax Kazantsev; CHECK: end: 566*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 0 567*0ddd5376SMax Kazantsev; 568cee313d2SEric Christopher 569cee313d2SEric Christopherentry: 570cee313d2SEric Christopher %l1 = load i64, i64* %P 571cee313d2SEric Christopher %c = icmp eq i64 %l1, 0 572cee313d2SEric Christopher br i1 %c, label %cond2, label %cond1 573cee313d2SEric Christopher 574cee313d2SEric Christophercond1: 575cee313d2SEric Christopher br i1 %c2, label %cond2, label %end 576cee313d2SEric Christopher 577cee313d2SEric Christophercond2: 578cee313d2SEric Christopher %l2 = load i64, i64* %P 579cee313d2SEric Christopher call void @fn2(i64 %l2) 580cee313d2SEric Christopher %c3 = icmp eq i64 %l2, 0 581cee313d2SEric Christopher br i1 %c3, label %cond3, label %end 582cee313d2SEric Christopher 583cee313d2SEric Christophercond3: 584cee313d2SEric Christopher call void @fn3(i64 %l2) 585cee313d2SEric Christopher br label %end 586cee313d2SEric Christopher 587cee313d2SEric Christopherend: 588cee313d2SEric Christopher ret i32 0 589cee313d2SEric Christopher} 590cee313d2SEric Christopher 591cee313d2SEric Christopherdefine i32 @fn_SinglePredMultihop(i1 %c1, i1 %c2,i64* %P) { 592*0ddd5376SMax Kazantsev; CHECK-LABEL: @fn_SinglePredMultihop( 593*0ddd5376SMax Kazantsev; CHECK-NEXT: entry: 594*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L1:%.*]] = load i64, i64* [[P:%.*]], align 4 595*0ddd5376SMax Kazantsev; CHECK-NEXT: [[C0:%.*]] = icmp eq i64 [[L1]], 0 596*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C0]], label [[COND3:%.*]], label [[COND0:%.*]] 597*0ddd5376SMax Kazantsev; CHECK: cond0: 598*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C1:%.*]], label [[COND1:%.*]], label [[END:%.*]] 599*0ddd5376SMax Kazantsev; CHECK: cond1: 600*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[C2:%.*]], label [[COND2:%.*]], label [[END]] 601*0ddd5376SMax Kazantsev; CHECK: cond2: 602*0ddd5376SMax Kazantsev; CHECK-NEXT: [[L2:%.*]] = phi i64 [ [[L1]], [[COND1]] ] 603*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn2(i64 [[L2]]) 604*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[END]] 605*0ddd5376SMax Kazantsev; CHECK: cond3: 606*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn2(i64 [[L1]]) 607*0ddd5376SMax Kazantsev; CHECK-NEXT: call void @fn3(i64 [[L1]]) 608*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[END]] 609*0ddd5376SMax Kazantsev; CHECK: end: 610*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 0 611*0ddd5376SMax Kazantsev; 612cee313d2SEric Christopher 613cee313d2SEric Christopherentry: 614cee313d2SEric Christopher %l1 = load i64, i64* %P 615cee313d2SEric Christopher %c0 = icmp eq i64 %l1, 0 616cee313d2SEric Christopher br i1 %c0, label %cond2, label %cond0 617cee313d2SEric Christopher 618cee313d2SEric Christophercond0: 619cee313d2SEric Christopher br i1 %c1, label %cond1, label %end 620cee313d2SEric Christopher 621cee313d2SEric Christophercond1: 622cee313d2SEric Christopher br i1 %c2, label %cond2, label %end 623cee313d2SEric Christopher 624cee313d2SEric Christophercond2: 625cee313d2SEric Christopher %l2 = load i64, i64* %P 626cee313d2SEric Christopher call void @fn2(i64 %l2) 627cee313d2SEric Christopher %c3 = icmp eq i64 %l2, 0 628cee313d2SEric Christopher br i1 %c3, label %cond3, label %end 629cee313d2SEric Christopher 630cee313d2SEric Christophercond3: 631cee313d2SEric Christopher call void @fn3(i64 %l2) 632cee313d2SEric Christopher br label %end 633cee313d2SEric Christopher 634cee313d2SEric Christopherend: 635cee313d2SEric Christopher ret i32 0 636cee313d2SEric Christopher} 637cee313d2SEric Christopher 638cee313d2SEric Christopherdeclare void @fn2(i64) 639cee313d2SEric Christopherdeclare void @fn3(i64) 640cee313d2SEric Christopher 641cee313d2SEric Christopher 642cee313d2SEric Christopher; Make sure we phi-translate and make the partially redundant load in 643cee313d2SEric Christopher; merge fully redudant and then we can jump-thread the block with the 644cee313d2SEric Christopher; store. 645cee313d2SEric Christopher; 646*0ddd5376SMax Kazantsevdefine i32 @phi_translate_partial_redundant_loads(i32, i32*, i32*) { 647*0ddd5376SMax Kazantsev; CHECK-LABEL: @phi_translate_partial_redundant_loads( 648*0ddd5376SMax Kazantsev; CHECK-NEXT: [[CMP0:%.*]] = icmp ne i32 [[TMP0:%.*]], 0 649*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[CMP0]], label [[MERGE_THREAD:%.*]], label [[MERGE:%.*]] 650cee313d2SEric Christopher; CHECK: merge.thread: 651*0ddd5376SMax Kazantsev; CHECK-NEXT: store i32 1, i32* [[TMP1:%.*]], align 4 652*0ddd5376SMax Kazantsev; CHECK-NEXT: br label [[LEFT_X:%.*]] 653*0ddd5376SMax Kazantsev; CHECK: merge: 654*0ddd5376SMax Kazantsev; CHECK-NEXT: [[NEWLOAD_PR:%.*]] = load i32, i32* [[TMP2:%.*]], align 4 655*0ddd5376SMax Kazantsev; CHECK-NEXT: [[CMP1:%.*]] = icmp slt i32 [[NEWLOAD_PR]], 5 656*0ddd5376SMax Kazantsev; CHECK-NEXT: br i1 [[CMP1]], label [[LEFT_X]], label [[RIGHT_X:%.*]] 657cee313d2SEric Christopher; CHECK: left_x: 658cee313d2SEric Christopher; CHECK-NEXT: ret i32 20 659*0ddd5376SMax Kazantsev; CHECK: right_x: 660*0ddd5376SMax Kazantsev; CHECK-NEXT: ret i32 10 661*0ddd5376SMax Kazantsev; 662cee313d2SEric Christopher %cmp0 = icmp ne i32 %0, 0 663cee313d2SEric Christopher br i1 %cmp0, label %left, label %right 664cee313d2SEric Christopher 665cee313d2SEric Christopherleft: 666cee313d2SEric Christopher store i32 1, i32* %1, align 4 667cee313d2SEric Christopher br label %merge 668cee313d2SEric Christopher 669cee313d2SEric Christopherright: 670cee313d2SEric Christopher br label %merge 671cee313d2SEric Christopher 672cee313d2SEric Christophermerge: 673cee313d2SEric Christopher %phiptr = phi i32* [ %1, %left ], [ %2, %right ] 674cee313d2SEric Christopher %newload = load i32, i32* %phiptr, align 4 675cee313d2SEric Christopher %cmp1 = icmp slt i32 %newload, 5 676cee313d2SEric Christopher br i1 %cmp1, label %left_x, label %right_x 677cee313d2SEric Christopher 678cee313d2SEric Christopherleft_x: 679cee313d2SEric Christopher ret i32 20 680cee313d2SEric Christopher 681cee313d2SEric Christopherright_x: 682cee313d2SEric Christopher ret i32 10 683cee313d2SEric Christopher} 684cee313d2SEric Christopher 685*0ddd5376SMax Kazantsev 686*0ddd5376SMax Kazantsev; CHECK: [[RNG4]] = !{i32 0, i32 1} 687cee313d2SEric Christopher 688cee313d2SEric Christopher!0 = !{!3, !3, i64 0} 689cee313d2SEric Christopher!1 = !{!"omnipotent char", !2} 690cee313d2SEric Christopher!2 = !{!"Simple C/C++ TBAA"} 691cee313d2SEric Christopher!3 = !{!"int", !1} 692cee313d2SEric Christopher!4 = !{ i32 0, i32 1 } 693cee313d2SEric Christopher!5 = !{ i32 8, i32 10 } 694cee313d2SEric Christopher!6 = !{!6} 695cee313d2SEric Christopher!7 = !{!7, !6} 696cee313d2SEric Christopher!8 = !{!8, !6} 697cee313d2SEric Christopher!9 = !{!7} 698cee313d2SEric Christopher!10 = !{!8} 699