brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.4 KiB · 8aa9003 Raw
397 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -S -passes=gvn-hoist < %s | FileCheck %s3 4; Checking gvn-hoist in case of indirect branches.5 6%class.bar = type { ptr, ptr }7%class.base = type { ptr }8 9@bar = local_unnamed_addr global ptr null, align 810@bar1 = local_unnamed_addr global ptr null, align 811 12; Check that the bitcast is not hoisted because it is after an indirect call13define i32 @foo(ptr nocapture readonly %i) {14; CHECK-LABEL: define i32 @foo15; CHECK-SAME: (ptr readonly captures(none) [[I:%.*]]) {16; CHECK-NEXT:  entry:17; CHECK-NEXT:    [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 818; CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 119; CHECK-NEXT:    [[Y:%.*]] = load ptr, ptr [[X]], align 820; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 421; CHECK-NEXT:    [[DOTOFF:%.*]] = add i32 [[TMP0]], -122; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[DOTOFF]], 223; CHECK-NEXT:    br i1 [[SWITCH]], label [[L1_PREHEADER:%.*]], label [[SW_DEFAULT:%.*]]24; CHECK:       l1.preheader:25; CHECK-NEXT:    [[B1:%.*]] = bitcast ptr [[Y]] to ptr26; CHECK-NEXT:    br label [[L1:%.*]]27; CHECK:       l1:28; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr @bar, align 829; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 [[TMP1]]()30; CHECK-NEXT:    [[B2:%.*]] = bitcast ptr [[Y]] to ptr31; CHECK-NEXT:    br label [[L1]]32; CHECK:       sw.default:33; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr @bar1, align 834; CHECK-NEXT:    [[CALL2:%.*]] = tail call i32 [[TMP2]]()35; CHECK-NEXT:    br label [[L1_PREHEADER]]36;37entry:38  %agg.tmp = alloca %class.bar, align 839  %x= getelementptr inbounds %class.bar, ptr %agg.tmp, i64 0, i32 140  %y = load ptr, ptr %x, align 841  %0 = load i32, ptr %i, align 442  %.off = add i32 %0, -143  %switch = icmp ult i32 %.off, 244  br i1 %switch, label %l1.preheader, label %sw.default45 46l1.preheader:                                     ; preds = %sw.default, %entry47  %b1 = bitcast ptr %y to ptr48  br label %l149 50l1:                                               ; preds = %l1.preheader, %l151  %1 = load ptr, ptr @bar, align 852  %call = tail call i32 %1()53  %b2 = bitcast ptr %y to ptr54  br label %l155 56sw.default:                                       ; preds = %entry57  %2 = load ptr, ptr @bar1, align 858  %call2 = tail call i32 %2()59  br label %l1.preheader60}61 62 63; Any instruction inside an infinite loop will not be hoisted because64; there is no path to exit of the function.65define i32 @foo1(ptr nocapture readonly %i) {66; CHECK-LABEL: define i32 @foo167; CHECK-SAME: (ptr readonly captures(none) [[I:%.*]]) {68; CHECK-NEXT:  entry:69; CHECK-NEXT:    [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 870; CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 171; CHECK-NEXT:    [[Y:%.*]] = load ptr, ptr [[X]], align 872; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 473; CHECK-NEXT:    [[DOTOFF:%.*]] = add i32 [[TMP0]], -174; CHECK-NEXT:    [[SWITCH:%.*]] = icmp ult i32 [[DOTOFF]], 275; CHECK-NEXT:    br i1 [[SWITCH]], label [[L1_PREHEADER:%.*]], label [[SW_DEFAULT:%.*]]76; CHECK:       l1.preheader:77; CHECK-NEXT:    [[B1:%.*]] = bitcast ptr [[Y]] to ptr78; CHECK-NEXT:    [[Y1:%.*]] = load ptr, ptr [[X]], align 879; CHECK-NEXT:    br label [[L1:%.*]]80; CHECK:       l1:81; CHECK-NEXT:    [[B2:%.*]] = bitcast ptr [[Y]] to ptr82; CHECK-NEXT:    [[TMP1:%.*]] = load ptr, ptr @bar, align 883; CHECK-NEXT:    [[Y2:%.*]] = load ptr, ptr [[X]], align 884; CHECK-NEXT:    [[CALL:%.*]] = tail call i32 [[TMP1]]()85; CHECK-NEXT:    br label [[L1]]86; CHECK:       sw.default:87; CHECK-NEXT:    [[TMP2:%.*]] = load ptr, ptr @bar1, align 888; CHECK-NEXT:    [[CALL2:%.*]] = tail call i32 [[TMP2]]()89; CHECK-NEXT:    br label [[L1_PREHEADER]]90;91entry:92  %agg.tmp = alloca %class.bar, align 893  %x= getelementptr inbounds %class.bar, ptr %agg.tmp, i64 0, i32 194  %y = load ptr, ptr %x, align 895  %0 = load i32, ptr %i, align 496  %.off = add i32 %0, -197  %switch = icmp ult i32 %.off, 298  br i1 %switch, label %l1.preheader, label %sw.default99 100l1.preheader:                                     ; preds = %sw.default, %entry101  %b1 = bitcast ptr %y to ptr102  %y1 = load ptr, ptr %x, align 8103  br label %l1104 105l1:                                               ; preds = %l1.preheader, %l1106  %b2 = bitcast ptr %y to ptr107  %1 = load ptr, ptr @bar, align 8108  %y2 = load ptr, ptr %x, align 8109  %call = tail call i32 %1()110  br label %l1111 112sw.default:                                       ; preds = %entry113  %2 = load ptr, ptr @bar1, align 8114  %call2 = tail call i32 %2()115  br label %l1.preheader116}117 118; Check that bitcast is hoisted even when one of them is partially redundant.119define i32 @test13(ptr %P, ptr %Ptr, ptr nocapture readonly %i) {120; CHECK-LABEL: define i32 @test13121; CHECK-SAME: (ptr [[P:%.*]], ptr [[PTR:%.*]], ptr readonly captures(none) [[I:%.*]]) {122; CHECK-NEXT:  entry:123; CHECK-NEXT:    [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 8124; CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 1125; CHECK-NEXT:    [[Y:%.*]] = load ptr, ptr [[X]], align 8126; CHECK-NEXT:    [[B2:%.*]] = bitcast ptr [[Y]] to ptr127; CHECK-NEXT:    indirectbr ptr [[PTR]], [label [[BRBLOCK:%.*]], label %B2]128; CHECK:       B2:129; CHECK-NEXT:    store i32 4, ptr [[P]], align 4130; CHECK-NEXT:    br label [[BRBLOCK]]131; CHECK:       BrBlock:132; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[P]], align 4133; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 42134; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]135; CHECK:       T:136; CHECK-NEXT:    ret i32 123137; CHECK:       F:138; CHECK-NEXT:    ret i32 1422139;140entry:141  %agg.tmp = alloca %class.bar, align 8142  %x= getelementptr inbounds %class.bar, ptr %agg.tmp, i64 0, i32 1143  %y = load ptr, ptr %x, align 8144  indirectbr ptr %Ptr, [label %BrBlock, label %B2]145 146B2:147  %b1 = bitcast ptr %y to ptr148  store i32 4, ptr %P149  br label %BrBlock150 151BrBlock:152  %b2 = bitcast ptr %y to ptr153  %L = load i32, ptr %P154  %C = icmp eq i32 %L, 42155  br i1 %C, label %T, label %F156 157T:158  ret i32 123159F:160  ret i32 1422161}162 163; Check that the bitcast is not hoisted because anticipability164; cannot be guaranteed here as one of the indirect branch targets165; do not have the bitcast instruction.166define i32 @test14(ptr %P, ptr %Ptr, ptr nocapture readonly %i) {167; CHECK-LABEL: define i32 @test14168; CHECK-SAME: (ptr [[P:%.*]], ptr [[PTR:%.*]], ptr readonly captures(none) [[I:%.*]]) {169; CHECK-NEXT:  entry:170; CHECK-NEXT:    [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 8171; CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 1172; CHECK-NEXT:    [[Y:%.*]] = load ptr, ptr [[X]], align 8173; CHECK-NEXT:    indirectbr ptr [[PTR]], [label [[BRBLOCK:%.*]], label [[B2:%.*]], label %T]174; CHECK:       B2:175; CHECK-NEXT:    [[B1:%.*]] = bitcast ptr [[Y]] to ptr176; CHECK-NEXT:    store i32 4, ptr [[P]], align 4177; CHECK-NEXT:    br label [[BRBLOCK]]178; CHECK:       BrBlock:179; CHECK-NEXT:    [[B2:%.*]] = bitcast ptr [[Y]] to ptr180; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[P]], align 4181; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 42182; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]183; CHECK:       T:184; CHECK-NEXT:    [[PI:%.*]] = load i32, ptr [[I]], align 4185; CHECK-NEXT:    ret i32 [[PI]]186; CHECK:       F:187; CHECK-NEXT:    [[PL:%.*]] = load i32, ptr [[P]], align 4188; CHECK-NEXT:    ret i32 [[PL]]189;190entry:191  %agg.tmp = alloca %class.bar, align 8192  %x= getelementptr inbounds %class.bar, ptr %agg.tmp, i64 0, i32 1193  %y = load ptr, ptr %x, align 8194  indirectbr ptr %Ptr, [label %BrBlock, label %B2, label %T]195 196B2:197  %b1 = bitcast ptr %y to ptr198  store i32 4, ptr %P199  br label %BrBlock200 201BrBlock:202  %b2 = bitcast ptr %y to ptr203  %L = load i32, ptr %P204  %C = icmp eq i32 %L, 42205  br i1 %C, label %T, label %F206 207T:208  %pi = load i32, ptr %i, align 4209  ret i32 %pi210F:211  %pl = load i32, ptr %P212  ret i32 %pl213}214 215 216; Check that the bitcast is not hoisted because of a cycle217; due to indirect branches218define i32 @test16(ptr %P, ptr %Ptr, ptr nocapture readonly %i) {219; CHECK-LABEL: define i32 @test16220; CHECK-SAME: (ptr [[P:%.*]], ptr [[PTR:%.*]], ptr readonly captures(none) [[I:%.*]]) {221; CHECK-NEXT:  entry:222; CHECK-NEXT:    [[AGG_TMP:%.*]] = alloca [[CLASS_BAR:%.*]], align 8223; CHECK-NEXT:    [[X:%.*]] = getelementptr inbounds [[CLASS_BAR]], ptr [[AGG_TMP]], i64 0, i32 1224; CHECK-NEXT:    [[Y:%.*]] = load ptr, ptr [[X]], align 8225; CHECK-NEXT:    indirectbr ptr [[PTR]], [label [[BRBLOCK:%.*]], label %B2]226; CHECK:       B2:227; CHECK-NEXT:    [[B1:%.*]] = bitcast ptr [[Y]] to ptr228; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4229; CHECK-NEXT:    store i32 [[TMP0]], ptr [[P]], align 4230; CHECK-NEXT:    br label [[BRBLOCK]]231; CHECK:       BrBlock:232; CHECK-NEXT:    [[B2:%.*]] = bitcast ptr [[Y]] to ptr233; CHECK-NEXT:    [[L:%.*]] = load i32, ptr [[P]], align 4234; CHECK-NEXT:    [[C:%.*]] = icmp eq i32 [[L]], 42235; CHECK-NEXT:    br i1 [[C]], label [[T:%.*]], label [[F:%.*]]236; CHECK:       T:237; CHECK-NEXT:    indirectbr ptr [[P]], [label [[BRBLOCK]], label %B2]238; CHECK:       F:239; CHECK-NEXT:    indirectbr ptr [[PTR]], [label [[BRBLOCK]], label %B2]240;241entry:242  %agg.tmp = alloca %class.bar, align 8243  %x= getelementptr inbounds %class.bar, ptr %agg.tmp, i64 0, i32 1244  %y = load ptr, ptr %x, align 8245  indirectbr ptr %Ptr, [label %BrBlock, label %B2]246 247B2:248  %b1 = bitcast ptr %y to ptr249  %0 = load i32, ptr %i, align 4250  store i32 %0, ptr %P251  br label %BrBlock252 253BrBlock:254  %b2 = bitcast ptr %y to ptr255  %L = load i32, ptr %P256  %C = icmp eq i32 %L, 42257  br i1 %C, label %T, label %F258 259T:260  indirectbr ptr %P, [label %BrBlock, label %B2]261 262F:263  indirectbr ptr %Ptr, [label %BrBlock, label %B2]264}265 266 267@_ZTIi = external constant ptr268 269; Check that an instruction is not hoisted out of landing pad (%lpad4)270; Also within a landing pad no redundancies are removed by gvn-hoist,271; however an instruction may be hoisted into a landing pad if272; landing pad has direct branches (e.g., %lpad to %catch1, %catch)273; This CFG has a cycle (%lpad -> %catch1 -> %lpad4 -> %lpad)274 275define i32 @foo2(ptr nocapture readonly %i) local_unnamed_addr personality ptr @__gxx_personality_v0 {276; CHECK-LABEL: define i32 @foo2277; CHECK-SAME: (ptr readonly captures(none) [[I:%.*]]) local_unnamed_addr personality ptr @__gxx_personality_v0 {278; CHECK-NEXT:  entry:279; CHECK-NEXT:    [[TMP0:%.*]] = load i32, ptr [[I]], align 4280; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[TMP0]], 0281; CHECK-NEXT:    br i1 [[CMP]], label [[TRY_CONT:%.*]], label [[IF_THEN:%.*]]282; CHECK:       if.then:283; CHECK-NEXT:    [[EXCEPTION:%.*]] = tail call ptr @__cxa_allocate_exception(i64 4) #[[ATTR1:[0-9]+]]284; CHECK-NEXT:    [[TMP1:%.*]] = bitcast ptr [[EXCEPTION]] to ptr285; CHECK-NEXT:    store i32 [[TMP0]], ptr [[TMP1]], align 16286; CHECK-NEXT:    invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIi, ptr null) #[[ATTR2:[0-9]+]]287; CHECK-NEXT:            to label [[UNREACHABLE:%.*]] unwind label [[LPAD:%.*]]288; CHECK:       lpad:289; CHECK-NEXT:    [[TMP2:%.*]] = landingpad { ptr, i32 }290; CHECK-NEXT:            catch ptr @_ZTIi291; CHECK-NEXT:            catch ptr null292; CHECK-NEXT:    [[BC1:%.*]] = add i32 [[TMP0]], 10293; CHECK-NEXT:    [[TMP3:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 0294; CHECK-NEXT:    [[TMP4:%.*]] = extractvalue { ptr, i32 } [[TMP2]], 1295; CHECK-NEXT:    [[TMP5:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #[[ATTR1]]296; CHECK-NEXT:    [[MATCHES:%.*]] = icmp eq i32 [[TMP4]], [[TMP5]]297; CHECK-NEXT:    [[BC7:%.*]] = add i32 [[TMP0]], 10298; CHECK-NEXT:    [[TMP6:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[TMP3]]) #[[ATTR1]]299; CHECK-NEXT:    [[BC4:%.*]] = add i32 [[TMP0]], 10300; CHECK-NEXT:    br i1 [[MATCHES]], label [[CATCH1:%.*]], label [[CATCH:%.*]]301; CHECK:       catch1:302; CHECK-NEXT:    invoke void @__cxa_rethrow() #[[ATTR2]]303; CHECK-NEXT:            to label [[UNREACHABLE]] unwind label [[LPAD4:%.*]]304; CHECK:       catch:305; CHECK-NEXT:    [[TMP7:%.*]] = load i32, ptr [[I]], align 4306; CHECK-NEXT:    [[ADD:%.*]] = add nsw i32 [[TMP7]], 1307; CHECK-NEXT:    tail call void @__cxa_end_catch()308; CHECK-NEXT:    br label [[TRY_CONT]]309; CHECK:       lpad4:310; CHECK-NEXT:    [[TMP8:%.*]] = landingpad { ptr, i32 }311; CHECK-NEXT:            cleanup312; CHECK-NEXT:    [[BC5:%.*]] = add i32 [[TMP0]], 10313; CHECK-NEXT:    tail call void @__cxa_end_catch() #[[ATTR1]]314; CHECK-NEXT:    invoke void @__cxa_throw(ptr [[EXCEPTION]], ptr @_ZTIi, ptr null) #[[ATTR2]]315; CHECK-NEXT:            to label [[UNREACHABLE]] unwind label [[LPAD]]316; CHECK:       try.cont:317; CHECK-NEXT:    [[K_0:%.*]] = phi i32 [ [[ADD]], [[CATCH]] ], [ 0, [[ENTRY:%.*]] ]318; CHECK-NEXT:    [[BC6:%.*]] = add i32 [[TMP0]], 10319; CHECK-NEXT:    ret i32 [[K_0]]320; CHECK:       unreachable:321; CHECK-NEXT:    [[BC2:%.*]] = add i32 [[TMP0]], 10322; CHECK-NEXT:    ret i32 [[BC2]]323;324entry:325  %0 = load i32, ptr %i, align 4326  %cmp = icmp eq i32 %0, 0327  br i1 %cmp, label %try.cont, label %if.then328 329if.then:330  %exception = tail call ptr @__cxa_allocate_exception(i64 4) #2331  %1 = bitcast ptr %exception to ptr332  store i32 %0, ptr %1, align 16333  invoke void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) #3334  to label %unreachable unwind label %lpad335 336lpad:337  %2 = landingpad { ptr, i32 }338  catch ptr @_ZTIi339  catch ptr null340  %bc1 = add i32 %0, 10341  %3 = extractvalue { ptr, i32 } %2, 0342  %4 = extractvalue { ptr, i32 } %2, 1343  %5 = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi) #2344  %matches = icmp eq i32 %4, %5345  %bc7 = add i32 %0, 10346  %6 = tail call ptr @__cxa_begin_catch(ptr %3) #2347  br i1 %matches, label %catch1, label %catch348 349catch1:350  %bc3 = add i32 %0, 10351  invoke void @__cxa_rethrow() #3352  to label %unreachable unwind label %lpad4353 354catch:355  %bc4 = add i32 %0, 10356  %7 = load i32, ptr %i, align 4357  %add = add nsw i32 %7, 1358  tail call void @__cxa_end_catch()359  br label %try.cont360 361lpad4:362  %8 = landingpad { ptr, i32 }363  cleanup364  %bc5 = add i32 %0, 10365  tail call void @__cxa_end_catch() #2366  invoke void @__cxa_throw(ptr %exception, ptr @_ZTIi, ptr null) #3367  to label %unreachable unwind label %lpad368 369try.cont:370  %k.0 = phi i32 [ %add, %catch ], [ 0, %entry ]371  %bc6 = add i32 %0, 10372  ret i32 %k.0373 374unreachable:375  %bc2 = add i32 %0, 10376  ret i32 %bc2377}378 379declare ptr @__cxa_allocate_exception(i64) local_unnamed_addr380 381declare void @__cxa_throw(ptr, ptr, ptr) local_unnamed_addr382 383declare i32 @__gxx_personality_v0(...)384 385; Function Attrs: nounwind readnone386declare i32 @llvm.eh.typeid.for.p0(ptr) #1387 388declare ptr @__cxa_begin_catch(ptr) local_unnamed_addr389 390declare void @__cxa_end_catch() local_unnamed_addr391 392declare void @__cxa_rethrow() local_unnamed_addr393 394attributes #1 = { nounwind readnone }395attributes #2 = { nounwind }396attributes #3 = { noreturn }397