1; RUN: opt -S -gvn-hoist < %s | FileCheck %s 2 3; Checking gvn-hoist in case of infinite loops and irreducible control flow. 4 5; Check that bitcast is not hoisted beacuse down safety is not guaranteed. 6; CHECK-LABEL: @bazv1 7; CHECK: if.then.i: 8; CHECK: bitcast 9; CHECK-NEXT: load 10; CHECK: if.then4.i: 11; CHECK: bitcast 12; CHECK-NEXT: load 13 14%class.bar = type { i8*, %class.base* } 15%class.base = type { i32 (...)** } 16 17; Function Attrs: noreturn nounwind uwtable 18define void @bazv1() local_unnamed_addr { 19entry: 20 %agg.tmp = alloca %class.bar, align 8 21 %x.sroa.2.0..sroa_idx2 = getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 22 store %class.base* null, %class.base** %x.sroa.2.0..sroa_idx2, align 8 23 call void @_Z3foo3bar(%class.bar* nonnull %agg.tmp) 24 %0 = load %class.base*, %class.base** %x.sroa.2.0..sroa_idx2, align 8 25 %1 = bitcast %class.bar* %agg.tmp to %class.base* 26 %cmp.i = icmp eq %class.base* %0, %1 27 br i1 %cmp.i, label %if.then.i, label %if.else.i 28 29if.then.i: ; preds = %entry 30 %2 = bitcast %class.base* %0 to void (%class.base*)*** 31 %vtable.i = load void (%class.base*)**, void (%class.base*)*** %2, align 8 32 %vfn.i = getelementptr inbounds void (%class.base*)*, void (%class.base*)** %vtable.i, i64 2 33 %3 = load void (%class.base*)*, void (%class.base*)** %vfn.i, align 8 34 call void %3(%class.base* %0) 35 br label %while.cond.preheader 36 37if.else.i: ; preds = %entry 38 %tobool.i = icmp eq %class.base* %0, null 39 br i1 %tobool.i, label %while.cond.preheader, label %if.then4.i 40 41if.then4.i: ; preds = %if.else.i 42 %4 = bitcast %class.base* %0 to void (%class.base*)*** 43 %vtable6.i = load void (%class.base*)**, void (%class.base*)*** %4, align 8 44 %vfn7.i = getelementptr inbounds void (%class.base*)*, void (%class.base*)** %vtable6.i, i64 3 45 %5 = load void (%class.base*)*, void (%class.base*)** %vfn7.i, align 8 46 call void %5(%class.base* nonnull %0) 47 br label %while.cond.preheader 48 49while.cond.preheader: ; preds = %if.then.i, %if.else.i, %if.then4.i 50 br label %while.cond 51 52while.cond: ; preds = %while.cond.preheader, %while.cond 53 %call = call i32 @sleep(i32 10) 54 br label %while.cond 55} 56 57declare void @_Z3foo3bar(%class.bar*) local_unnamed_addr 58 59declare i32 @sleep(i32) local_unnamed_addr 60 61; Check that the load is hoisted even if it is inside an irreducible control flow 62; because the load is anticipable on all paths. 63 64; CHECK-LABEL: @bazv 65; CHECK: bb2: 66; CHECK-NOT: load 67; CHECK-NOT: bitcast 68 69define void @bazv() { 70entry: 71 %agg.tmp = alloca %class.bar, align 8 72 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 73 %0 = load %class.base*, %class.base** %x, align 8 74 %1 = bitcast %class.bar* %agg.tmp to %class.base* 75 %cmp.i = icmp eq %class.base* %0, %1 76 br i1 %cmp.i, label %bb1, label %bb4 77 78bb1: 79 %b1 = bitcast %class.base* %0 to void (%class.base*)*** 80 %i = load void (%class.base*)**, void (%class.base*)*** %b1, align 8 81 %vfn.i = getelementptr inbounds void (%class.base*)*, void (%class.base*)** %i, i64 2 82 %cmp.j = icmp eq %class.base* %0, %1 83 br i1 %cmp.j, label %bb2, label %bb3 84 85bb2: 86 %l1 = load void (%class.base*)*, void (%class.base*)** %vfn.i, align 8 87 br label %bb3 88 89bb3: 90 %l2 = load void (%class.base*)*, void (%class.base*)** %vfn.i, align 8 91 br label %bb2 92 93bb4: 94 %b2 = bitcast %class.base* %0 to void (%class.base*)*** 95 ret void 96} 97