11db2551cSBjorn Pettersson; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -verify-dom-info -verify-memoryssa -S %s | FileCheck %s 21db2551cSBjorn Pettersson; RUN: opt -passes='loop-mssa(simple-loop-unswitch<nontrivial>),verify<loops>' -memssa-check-limit=3 -verify-dom-info -verify-memoryssa -S %s | FileCheck %s 3f3a27511SJingu Kang 4f3a27511SJingu Kangdeclare void @clobber() 5f3a27511SJingu Kang 6f3a27511SJingu Kang; Check that MemorySSA updating can deal with a clobbering access of a 7f3a27511SJingu Kang; duplicated load being a MemoryPHI outside the loop. 8*2f79f543SNikita Popovdefine void @partial_unswitch_memssa_update(ptr noalias %ptr, i1 %c) { 9f3a27511SJingu Kang; CHECK-LABEL: @partial_unswitch_memssa_update( 10f3a27511SJingu Kang; CHECK-LABEL: loop.ph: 11*2f79f543SNikita Popov; CHECK-NEXT: [[LV:%[a-z0-9]+]] = load i32, ptr %ptr, align 4 12f3a27511SJingu Kang; CHECK-NEXT: [[C:%[a-z0-9]+]] = icmp eq i32 [[LV]], 0 13f3a27511SJingu Kang; CHECK-NEXT: br i1 [[C]] 14f3a27511SJingu Kangentry: 15f3a27511SJingu Kang br i1 %c, label %loop.ph, label %outside.clobber 16f3a27511SJingu Kang 17f3a27511SJingu Kangoutside.clobber: 18f3a27511SJingu Kang call void @clobber() 19f3a27511SJingu Kang br label %loop.ph 20f3a27511SJingu Kang 21f3a27511SJingu Kangloop.ph: 22f3a27511SJingu Kang br label %loop.header 23f3a27511SJingu Kang 24f3a27511SJingu Kangloop.header: 25*2f79f543SNikita Popov %lv = load i32, ptr %ptr, align 4 26f3a27511SJingu Kang %hc = icmp eq i32 %lv, 0 27f3a27511SJingu Kang br i1 %hc, label %if, label %then 28f3a27511SJingu Kang 29f3a27511SJingu Kangif: 30f3a27511SJingu Kang br label %loop.latch 31f3a27511SJingu Kang 32f3a27511SJingu Kangthen: 33f3a27511SJingu Kang br label %loop.latch 34f3a27511SJingu Kang 35f3a27511SJingu Kangloop.latch: 36f3a27511SJingu Kang br i1 true, label %loop.header, label %exit 37f3a27511SJingu Kang 38f3a27511SJingu Kangexit: 39f3a27511SJingu Kang ret void 40f3a27511SJingu Kang} 41f3a27511SJingu Kang 42f3a27511SJingu Kang; Check that MemorySSA updating can deal with skipping defining accesses in the 43f3a27511SJingu Kang; loop body until it finds the first defining access outside the loop. 44*2f79f543SNikita Popovdefine void @partial_unswitch_inloop_stores_beteween_outside_defining_access(ptr noalias %ptr, ptr noalias %src) { 45f3a27511SJingu Kang; CHECK-LABEL: @partial_unswitch_inloop_stores_beteween_outside_defining_access 46f3a27511SJingu Kang; CHECK-LABEL: entry: 47*2f79f543SNikita Popov; CHECK-NEXT: store i64 0, ptr %ptr, align 1 48*2f79f543SNikita Popov; CHECK-NEXT: store i64 1, ptr %ptr, align 1 49*2f79f543SNikita Popov; CHECK-NEXT: [[LV:%[a-z0-9]+]] = load i16, ptr %src, align 1 50f3a27511SJingu Kang; CHECK-NEXT: [[C:%[a-z0-9]+]] = icmp eq i16 [[LV]], 0 51f3a27511SJingu Kang; CHECK-NEXT: br i1 [[C]] 52f3a27511SJingu Kang; 53f3a27511SJingu Kangentry: 54*2f79f543SNikita Popov store i64 0, ptr %ptr, align 1 55*2f79f543SNikita Popov store i64 1, ptr %ptr, align 1 56f3a27511SJingu Kang br label %loop 57f3a27511SJingu Kang 58f3a27511SJingu Kangloop: 59f3a27511SJingu Kang %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop.latch ] 60*2f79f543SNikita Popov store i64 2, ptr %ptr, align 1 61*2f79f543SNikita Popov %lv = load i16, ptr %src, align 1 62f3a27511SJingu Kang %invar.cond = icmp eq i16 %lv, 0 63f3a27511SJingu Kang br i1 %invar.cond, label %noclobber, label %loop.latch 64f3a27511SJingu Kang 65f3a27511SJingu Kangnoclobber: 66f3a27511SJingu Kang br label %loop.latch 67f3a27511SJingu Kang 68f3a27511SJingu Kangloop.latch: 69f3a27511SJingu Kang %iv.next = add i32 %iv, 1 70f3a27511SJingu Kang %ec = icmp eq i32 %iv, 1000 71f3a27511SJingu Kang br i1 %ec, label %exit, label %loop 72f3a27511SJingu Kang 73f3a27511SJingu Kangexit: 74f3a27511SJingu Kang ret void 75f3a27511SJingu Kang} 76f3a27511SJingu Kang 77