1; RUN: opt -S -gvn-hoist < %s | FileCheck %s 2 3; Checking gvn-hoist in case of indirect branches. 4 5; Check that the bitcast is not hoisted because it is after an indirect call 6; CHECK-LABEL: @foo 7; CHECK-LABEL: l1.preheader: 8; CHECK-NEXT: bitcast 9; CHECK-LABEL: l1 10; CHECK: bitcast 11 12%class.bar = type { i8*, %class.base* } 13%class.base = type { i32 (...)** } 14 15@bar = local_unnamed_addr global i32 ()* null, align 8 16@bar1 = local_unnamed_addr global i32 ()* null, align 8 17 18define i32 @foo(i32* nocapture readonly %i) { 19entry: 20 %agg.tmp = alloca %class.bar, align 8 21 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 22 %y = load %class.base*, %class.base** %x, align 8 23 %0 = load i32, i32* %i, align 4 24 %.off = add i32 %0, -1 25 %switch = icmp ult i32 %.off, 2 26 br i1 %switch, label %l1.preheader, label %sw.default 27 28l1.preheader: ; preds = %sw.default, %entry 29 %b1 = bitcast %class.base* %y to void (%class.base*)*** 30 br label %l1 31 32l1: ; preds = %l1.preheader, %l1 33 %1 = load i32 ()*, i32 ()** @bar, align 8 34 %call = tail call i32 %1() 35 %b2 = bitcast %class.base* %y to void (%class.base*)*** 36 br label %l1 37 38sw.default: ; preds = %entry 39 %2 = load i32 ()*, i32 ()** @bar1, align 8 40 %call2 = tail call i32 %2() 41 br label %l1.preheader 42} 43 44 45; Any instruction inside an infinite loop will not be hoisted because 46; there is no path to exit of the function. 47 48; CHECK-LABEL: @foo1 49; CHECK-LABEL: l1.preheader: 50; CHECK-NEXT: bitcast 51; CHECK-LABEL: l1: 52; CHECK: bitcast 53 54define i32 @foo1(i32* nocapture readonly %i) { 55entry: 56 %agg.tmp = alloca %class.bar, align 8 57 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 58 %y = load %class.base*, %class.base** %x, align 8 59 %0 = load i32, i32* %i, align 4 60 %.off = add i32 %0, -1 61 %switch = icmp ult i32 %.off, 2 62 br i1 %switch, label %l1.preheader, label %sw.default 63 64l1.preheader: ; preds = %sw.default, %entry 65 %b1 = bitcast %class.base* %y to void (%class.base*)*** 66 %y1 = load %class.base*, %class.base** %x, align 8 67 br label %l1 68 69l1: ; preds = %l1.preheader, %l1 70 %b2 = bitcast %class.base* %y to void (%class.base*)*** 71 %1 = load i32 ()*, i32 ()** @bar, align 8 72 %y2 = load %class.base*, %class.base** %x, align 8 73 %call = tail call i32 %1() 74 br label %l1 75 76sw.default: ; preds = %entry 77 %2 = load i32 ()*, i32 ()** @bar1, align 8 78 %call2 = tail call i32 %2() 79 br label %l1.preheader 80} 81 82; Check that bitcast is hoisted even when one of them is partially redundant. 83; CHECK-LABEL: @test13 84; CHECK: bitcast 85; CHECK-NOT: bitcast 86 87define i32 @test13(i32* %P, i8* %Ptr, i32* nocapture readonly %i) { 88entry: 89 %agg.tmp = alloca %class.bar, align 8 90 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 91 %y = load %class.base*, %class.base** %x, align 8 92 indirectbr i8* %Ptr, [label %BrBlock, label %B2] 93 94B2: 95 %b1 = bitcast %class.base* %y to void (%class.base*)*** 96 store i32 4, i32 *%P 97 br label %BrBlock 98 99BrBlock: 100 %b2 = bitcast %class.base* %y to void (%class.base*)*** 101 %L = load i32, i32* %P 102 %C = icmp eq i32 %L, 42 103 br i1 %C, label %T, label %F 104 105T: 106 ret i32 123 107F: 108 ret i32 1422 109} 110 111; Check that the bitcast is not hoisted because anticipability 112; cannot be guaranteed here as one of the indirect branch targets 113; do not have the bitcast instruction. 114 115; CHECK-LABEL: @test14 116; CHECK-LABEL: B2: 117; CHECK-NEXT: bitcast 118; CHECK-LABEL: BrBlock: 119; CHECK-NEXT: bitcast 120 121define i32 @test14(i32* %P, i8* %Ptr, i32* nocapture readonly %i) { 122entry: 123 %agg.tmp = alloca %class.bar, align 8 124 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 125 %y = load %class.base*, %class.base** %x, align 8 126 indirectbr i8* %Ptr, [label %BrBlock, label %B2, label %T] 127 128B2: 129 %b1 = bitcast %class.base* %y to void (%class.base*)*** 130 store i32 4, i32 *%P 131 br label %BrBlock 132 133BrBlock: 134 %b2 = bitcast %class.base* %y to void (%class.base*)*** 135 %L = load i32, i32* %P 136 %C = icmp eq i32 %L, 42 137 br i1 %C, label %T, label %F 138 139T: 140 %pi = load i32, i32* %i, align 4 141 ret i32 %pi 142F: 143 %pl = load i32, i32* %P 144 ret i32 %pl 145} 146 147 148; Check that the bitcast is not hoisted because of a cycle 149; due to indirect branches 150; CHECK-LABEL: @test16 151; CHECK-LABEL: B2: 152; CHECK-NEXT: bitcast 153; CHECK-LABEL: BrBlock: 154; CHECK-NEXT: bitcast 155 156define i32 @test16(i32* %P, i8* %Ptr, i32* nocapture readonly %i) { 157entry: 158 %agg.tmp = alloca %class.bar, align 8 159 %x= getelementptr inbounds %class.bar, %class.bar* %agg.tmp, i64 0, i32 1 160 %y = load %class.base*, %class.base** %x, align 8 161 indirectbr i8* %Ptr, [label %BrBlock, label %B2] 162 163B2: 164 %b1 = bitcast %class.base* %y to void (%class.base*)*** 165 %0 = load i32, i32* %i, align 4 166 store i32 %0, i32 *%P 167 br label %BrBlock 168 169BrBlock: 170 %b2 = bitcast %class.base* %y to void (%class.base*)*** 171 %L = load i32, i32* %P 172 %C = icmp eq i32 %L, 42 173 br i1 %C, label %T, label %F 174 175T: 176 indirectbr i32* %P, [label %BrBlock, label %B2] 177 178F: 179 indirectbr i8* %Ptr, [label %BrBlock, label %B2] 180} 181 182 183@_ZTIi = external constant i8* 184 185; Check that an instruction is not hoisted out of landing pad (%lpad4) 186; Also within a landing pad no redundancies are removed by gvn-hoist, 187; however an instruction may be hoisted into a landing pad if 188; landing pad has direct branches (e.g., %lpad to %catch1, %catch) 189; This CFG has a cycle (%lpad -> %catch1 -> %lpad4 -> %lpad) 190 191; CHECK-LABEL: @foo2 192; Check that nothing gets hoisted out of %lpad 193; CHECK-LABEL: lpad: 194; CHECK: %bc1 = add i32 %0, 10 195; CHECK: %bc7 = add i32 %0, 10 196 197; Check that the add is hoisted 198; CHECK-LABEL: catch1: 199; CHECK-NEXT: invoke 200 201; Check that the add is hoisted 202; CHECK-LABEL: catch: 203; CHECK-NEXT: load 204 205; Check that other adds are not hoisted 206; CHECK-LABEL: lpad4: 207; CHECK: %bc5 = add i32 %0, 10 208; CHECK-LABEL: unreachable: 209; CHECK: %bc2 = add i32 %0, 10 210 211; Function Attrs: noinline uwtable 212define i32 @foo2(i32* nocapture readonly %i) local_unnamed_addr personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 213entry: 214 %0 = load i32, i32* %i, align 4 215 %cmp = icmp eq i32 %0, 0 216 br i1 %cmp, label %try.cont, label %if.then 217 218if.then: 219 %exception = tail call i8* @__cxa_allocate_exception(i64 4) #2 220 %1 = bitcast i8* %exception to i32* 221 store i32 %0, i32* %1, align 16 222 invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3 223 to label %unreachable unwind label %lpad 224 225lpad: 226 %2 = landingpad { i8*, i32 } 227 catch i8* bitcast (i8** @_ZTIi to i8*) 228 catch i8* null 229 %bc1 = add i32 %0, 10 230 %3 = extractvalue { i8*, i32 } %2, 0 231 %4 = extractvalue { i8*, i32 } %2, 1 232 %5 = tail call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) #2 233 %matches = icmp eq i32 %4, %5 234 %bc7 = add i32 %0, 10 235 %6 = tail call i8* @__cxa_begin_catch(i8* %3) #2 236 br i1 %matches, label %catch1, label %catch 237 238catch1: 239 %bc3 = add i32 %0, 10 240 invoke void @__cxa_rethrow() #3 241 to label %unreachable unwind label %lpad4 242 243catch: 244 %bc4 = add i32 %0, 10 245 %7 = load i32, i32* %i, align 4 246 %add = add nsw i32 %7, 1 247 tail call void @__cxa_end_catch() 248 br label %try.cont 249 250lpad4: 251 %8 = landingpad { i8*, i32 } 252 cleanup 253 %bc5 = add i32 %0, 10 254 tail call void @__cxa_end_catch() #2 255 invoke void @__cxa_throw(i8* %exception, i8* bitcast (i8** @_ZTIi to i8*), i8* null) #3 256 to label %unreachable unwind label %lpad 257 258try.cont: 259 %k.0 = phi i32 [ %add, %catch ], [ 0, %entry ] 260 %bc6 = add i32 %0, 10 261 ret i32 %k.0 262 263unreachable: 264 %bc2 = add i32 %0, 10 265 ret i32 %bc2 266} 267 268declare i8* @__cxa_allocate_exception(i64) local_unnamed_addr 269 270declare void @__cxa_throw(i8*, i8*, i8*) local_unnamed_addr 271 272declare i32 @__gxx_personality_v0(...) 273 274; Function Attrs: nounwind readnone 275declare i32 @llvm.eh.typeid.for(i8*) #1 276 277declare i8* @__cxa_begin_catch(i8*) local_unnamed_addr 278 279declare void @__cxa_end_catch() local_unnamed_addr 280 281declare void @__cxa_rethrow() local_unnamed_addr 282 283attributes #1 = { nounwind readnone } 284attributes #2 = { nounwind } 285attributes #3 = { noreturn } 286