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 18 define void @bazv1() local_unnamed_addr { 19 entry: 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 29 if.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 37 if.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 41 if.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 49 while.cond.preheader: ; preds = %if.then.i, %if.else.i, %if.then4.i 50 br label %while.cond 51 52 while.cond: ; preds = %while.cond.preheader, %while.cond 53 %call = call i32 @sleep(i32 10) 54 br label %while.cond 55 } 56 57 declare void @_Z3foo3bar(%class.bar*) local_unnamed_addr 58 59 declare 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 69 define void @bazv() { 70 entry: 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 78 bb1: 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 85 bb2: 86 %l1 = load void (%class.base*)*, void (%class.base*)** %vfn.i, align 8 87 br label %bb3 88 89 bb3: 90 %l2 = load void (%class.base*)*, void (%class.base*)** %vfn.i, align 8 91 br label %bb2 92 93 bb4: 94 %b2 = bitcast %class.base* %0 to void (%class.base*)*** 95 ret void 96 } 97