brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.0 KiB · c1b919d Raw
293 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes='require<profile-summary>,function(codegenprepare)' -S < %s | FileCheck %s3target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"4target triple = "x86_64-unknown-linux-gnu"5 6declare void @use(i32) local_unnamed_addr7declare void @useptr(ptr) local_unnamed_addr8 9; CHECK: @simple.targets = constant [2 x ptr] [ptr blockaddress(@simple, %bb0), ptr blockaddress(@simple, %bb1)], align 1610@simple.targets = constant [2 x ptr] [ptr blockaddress(@simple, %bb0), ptr blockaddress(@simple, %bb1)], align 1611 12; CHECK: @multi.targets = constant [2 x ptr] [ptr blockaddress(@multi, %bb0), ptr blockaddress(@multi, %bb1)], align 1613@multi.targets = constant [2 x ptr] [ptr blockaddress(@multi, %bb0), ptr blockaddress(@multi, %bb1)], align 1614 15; CHECK: @loop.targets = constant [2 x ptr] [ptr blockaddress(@loop, %bb0), ptr blockaddress(@loop, %bb1)], align 1616@loop.targets = constant [2 x ptr] [ptr blockaddress(@loop, %bb0), ptr blockaddress(@loop, %bb1)], align 1617 18; CHECK: @nophi.targets = constant [2 x ptr] [ptr blockaddress(@nophi, %bb0), ptr blockaddress(@nophi, %bb1)], align 1619@nophi.targets = constant [2 x ptr] [ptr blockaddress(@nophi, %bb0), ptr blockaddress(@nophi, %bb1)], align 1620 21; CHECK: @noncritical.targets = constant [2 x ptr] [ptr blockaddress(@noncritical, %bb0), ptr blockaddress(@noncritical, %bb1)], align 1622@noncritical.targets = constant [2 x ptr] [ptr blockaddress(@noncritical, %bb0), ptr blockaddress(@noncritical, %bb1)], align 1623 24; Check that we break the critical edge when an jump table has only one use.25define void @simple(ptr nocapture readonly %p) {26; CHECK-LABEL: @simple(27; CHECK-NEXT:  entry:28; CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 129; CHECK-NEXT:    [[INITVAL:%.*]] = load i32, ptr [[P]], align 430; CHECK-NEXT:    [[INITOP:%.*]] = load i32, ptr [[INCDEC_PTR]], align 431; CHECK-NEXT:    switch i32 [[INITOP]], label [[EXIT:%.*]] [32; CHECK-NEXT:    i32 0, label [[BB0_CLONE:%.*]]33; CHECK-NEXT:    i32 1, label [[BB1_CLONE:%.*]]34; CHECK-NEXT:    ]35; CHECK:       bb0:36; CHECK-NEXT:    br label [[DOTSPLIT:%.*]]37; CHECK:       .split:38; CHECK-NEXT:    [[MERGE:%.*]] = phi ptr [ [[PTR:%.*]], [[BB0:%.*]] ], [ [[INCDEC_PTR]], [[BB0_CLONE]] ]39; CHECK-NEXT:    [[MERGE2:%.*]] = phi i32 [ 0, [[BB0]] ], [ [[INITVAL]], [[BB0_CLONE]] ]40; CHECK-NEXT:    tail call void @use(i32 [[MERGE2]])41; CHECK-NEXT:    br label [[INDIRECTGOTO:%.*]]42; CHECK:       bb1:43; CHECK-NEXT:    br label [[DOTSPLIT3:%.*]]44; CHECK:       .split3:45; CHECK-NEXT:    [[MERGE5:%.*]] = phi ptr [ [[PTR]], [[BB1:%.*]] ], [ [[INCDEC_PTR]], [[BB1_CLONE]] ]46; CHECK-NEXT:    [[MERGE7:%.*]] = phi i32 [ 1, [[BB1]] ], [ [[INITVAL]], [[BB1_CLONE]] ]47; CHECK-NEXT:    tail call void @use(i32 [[MERGE7]])48; CHECK-NEXT:    br label [[INDIRECTGOTO]]49; CHECK:       indirectgoto:50; CHECK-NEXT:    [[P_ADDR_SINK:%.*]] = phi ptr [ [[MERGE5]], [[DOTSPLIT3]] ], [ [[MERGE]], [[DOTSPLIT]] ]51; CHECK-NEXT:    [[PTR]] = getelementptr inbounds i32, ptr [[P_ADDR_SINK]], i64 152; CHECK-NEXT:    [[NEWP:%.*]] = load i32, ptr [[P_ADDR_SINK]], align 453; CHECK-NEXT:    [[IDX:%.*]] = sext i32 [[NEWP]] to i6454; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr], ptr @simple.targets, i64 0, i64 [[IDX]]55; CHECK-NEXT:    [[NEWOP:%.*]] = load ptr, ptr [[ARRAYIDX]], align 856; CHECK-NEXT:    indirectbr ptr [[NEWOP]], [label [[BB0]], label %bb1]57; CHECK:       exit:58; CHECK-NEXT:    ret void59; CHECK:       bb0.clone:60; CHECK-NEXT:    br label [[DOTSPLIT]]61; CHECK:       bb1.clone:62; CHECK-NEXT:    br label [[DOTSPLIT3]]63;64entry:65  %incdec.ptr = getelementptr inbounds i32, ptr %p, i64 166  %initval = load i32, ptr %p, align 467  %initop = load i32, ptr %incdec.ptr, align 468  switch i32 %initop, label %exit [69  i32 0, label %bb070  i32 1, label %bb171  ]72 73bb0:74  %p.addr.0 = phi ptr [ %incdec.ptr, %entry ], [ %ptr, %indirectgoto ]75  %opcode.0 = phi i32 [ %initval, %entry ], [ 0, %indirectgoto ]76  tail call void @use(i32 %opcode.0)77  br label %indirectgoto78 79bb1:80  %p.addr.1 = phi ptr [ %incdec.ptr, %entry ], [ %ptr, %indirectgoto ]81  %opcode.1 = phi i32 [ %initval, %entry ], [ 1, %indirectgoto ]82  tail call void @use(i32 %opcode.1)83  br label %indirectgoto84 85indirectgoto:86  %p.addr.sink = phi ptr [ %p.addr.1, %bb1 ], [ %p.addr.0, %bb0 ]87  %ptr = getelementptr inbounds i32, ptr %p.addr.sink, i64 188  %newp = load i32, ptr %p.addr.sink, align 489  %idx = sext i32 %newp to i6490  %arrayidx = getelementptr inbounds [2 x ptr], ptr @simple.targets, i64 0, i64 %idx91  %newop = load ptr, ptr %arrayidx, align 892  indirectbr ptr %newop, [label %bb0, label %bb1]93 94exit:95  ret void96}97 98; Don't try to break critical edges when several indirectbr point to a single block99define void @multi(ptr nocapture readonly %p) {100; CHECK-LABEL: @multi(101; CHECK-NEXT:  entry:102; CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1103; CHECK-NEXT:    [[INITVAL:%.*]] = load i32, ptr [[P]], align 4104; CHECK-NEXT:    [[INITOP:%.*]] = load i32, ptr [[INCDEC_PTR]], align 4105; CHECK-NEXT:    switch i32 [[INITOP]], label [[EXIT:%.*]] [106; CHECK-NEXT:    i32 0, label [[BB0:%.*]]107; CHECK-NEXT:    i32 1, label [[BB1:%.*]]108; CHECK-NEXT:    ]109; CHECK:       bb0:110; CHECK-NEXT:    [[P_ADDR_0:%.*]] = phi ptr [ [[INCDEC_PTR]], [[ENTRY:%.*]] ], [ [[NEXT0:%.*]], [[BB0]] ], [ [[NEXT1:%.*]], [[BB1]] ]111; CHECK-NEXT:    [[OPCODE_0:%.*]] = phi i32 [ [[INITVAL]], [[ENTRY]] ], [ 0, [[BB0]] ], [ 1, [[BB1]] ]112; CHECK-NEXT:    tail call void @use(i32 [[OPCODE_0]])113; CHECK-NEXT:    [[NEXT0]] = getelementptr inbounds i32, ptr [[P_ADDR_0]], i64 1114; CHECK-NEXT:    [[NEWP0:%.*]] = load i32, ptr [[P_ADDR_0]], align 4115; CHECK-NEXT:    [[IDX0:%.*]] = sext i32 [[NEWP0]] to i64116; CHECK-NEXT:    [[ARRAYIDX0:%.*]] = getelementptr inbounds [2 x ptr], ptr @multi.targets, i64 0, i64 [[IDX0]]117; CHECK-NEXT:    [[NEWOP0:%.*]] = load ptr, ptr [[ARRAYIDX0]], align 8118; CHECK-NEXT:    indirectbr ptr [[NEWOP0]], [label [[BB0]], label %bb1]119; CHECK:       bb1:120; CHECK-NEXT:    [[P_ADDR_1:%.*]] = phi ptr [ [[INCDEC_PTR]], [[ENTRY]] ], [ [[NEXT0]], [[BB0]] ], [ [[NEXT1]], [[BB1]] ]121; CHECK-NEXT:    [[OPCODE_1:%.*]] = phi i32 [ [[INITVAL]], [[ENTRY]] ], [ 0, [[BB0]] ], [ 1, [[BB1]] ]122; CHECK-NEXT:    tail call void @use(i32 [[OPCODE_1]])123; CHECK-NEXT:    [[NEXT1]] = getelementptr inbounds i32, ptr [[P_ADDR_1]], i64 1124; CHECK-NEXT:    [[NEWP1:%.*]] = load i32, ptr [[P_ADDR_1]], align 4125; CHECK-NEXT:    [[IDX1:%.*]] = sext i32 [[NEWP1]] to i64126; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds [2 x ptr], ptr @multi.targets, i64 0, i64 [[IDX1]]127; CHECK-NEXT:    [[NEWOP1:%.*]] = load ptr, ptr [[ARRAYIDX1]], align 8128; CHECK-NEXT:    indirectbr ptr [[NEWOP1]], [label [[BB0]], label %bb1]129; CHECK:       exit:130; CHECK-NEXT:    ret void131;132entry:133  %incdec.ptr = getelementptr inbounds i32, ptr %p, i64 1134  %initval = load i32, ptr %p, align 4135  %initop = load i32, ptr %incdec.ptr, align 4136  switch i32 %initop, label %exit [137  i32 0, label %bb0138  i32 1, label %bb1139  ]140 141bb0:142  %p.addr.0 = phi ptr [ %incdec.ptr, %entry ], [ %next0, %bb0 ], [ %next1, %bb1 ]143  %opcode.0 = phi i32 [ %initval, %entry ], [ 0, %bb0 ], [ 1, %bb1 ]144  tail call void @use(i32 %opcode.0)145  %next0 = getelementptr inbounds i32, ptr %p.addr.0, i64 1146  %newp0 = load i32, ptr %p.addr.0, align 4147  %idx0 = sext i32 %newp0 to i64148  %arrayidx0 = getelementptr inbounds [2 x ptr], ptr @multi.targets, i64 0, i64 %idx0149  %newop0 = load ptr, ptr %arrayidx0, align 8150  indirectbr ptr %newop0, [label %bb0, label %bb1]151 152bb1:153  %p.addr.1 = phi ptr [ %incdec.ptr, %entry ], [ %next0, %bb0 ], [ %next1, %bb1 ]154  %opcode.1 = phi i32 [ %initval, %entry ], [ 0, %bb0 ], [ 1, %bb1 ]155  tail call void @use(i32 %opcode.1)156  %next1 = getelementptr inbounds i32, ptr %p.addr.1, i64 1157  %newp1 = load i32, ptr %p.addr.1, align 4158  %idx1 = sext i32 %newp1 to i64159  %arrayidx1 = getelementptr inbounds [2 x ptr], ptr @multi.targets, i64 0, i64 %idx1160  %newop1 = load ptr, ptr %arrayidx1, align 8161  indirectbr ptr %newop1, [label %bb0, label %bb1]162 163exit:164  ret void165}166 167; Make sure we do the right thing for cases where the indirectbr branches to168; the block it terminates.169define i64 @loop(ptr nocapture readonly %p) {170; CHECK-LABEL: @loop(171; CHECK-NEXT:  entry:172; CHECK-NEXT:    br label [[DOTSPLIT:%.*]]173; CHECK:       bb0:174; CHECK-NEXT:    br label [[DOTSPLIT]]175; CHECK:       .split:176; CHECK-NEXT:    [[MERGE:%.*]] = phi i64 [ [[I_NEXT:%.*]], [[BB0:%.*]] ], [ 0, [[ENTRY:%.*]] ]177; CHECK-NEXT:    [[TMP0:%.*]] = getelementptr inbounds i64, ptr [[P:%.*]], i64 [[MERGE]]178; CHECK-NEXT:    store i64 [[MERGE]], ptr [[TMP0]], align 4179; CHECK-NEXT:    [[I_NEXT]] = add nuw nsw i64 [[MERGE]], 1180; CHECK-NEXT:    [[IDX:%.*]] = srem i64 [[MERGE]], 2181; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr], ptr @loop.targets, i64 0, i64 [[IDX]]182; CHECK-NEXT:    [[TARGET:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8183; CHECK-NEXT:    indirectbr ptr [[TARGET]], [label [[BB0]], label %bb1]184; CHECK:       bb1:185; CHECK-NEXT:    ret i64 [[I_NEXT]]186;187entry:188  br label %bb0189 190bb0:191  %i = phi i64 [ %i.next, %bb0 ], [ 0, %entry ]192  %tmp0 = getelementptr inbounds i64, ptr %p, i64 %i193  store i64 %i, ptr %tmp0, align 4194  %i.next = add nuw nsw i64 %i, 1195  %idx = srem i64 %i, 2196  %arrayidx = getelementptr inbounds [2 x ptr], ptr @loop.targets, i64 0, i64 %idx197  %target = load ptr, ptr %arrayidx, align 8198  indirectbr ptr %target, [label %bb0, label %bb1]199 200bb1:201  ret i64 %i.next202}203 204; Don't do anything for cases that contain no phis.205define void @nophi(ptr %p) {206; CHECK-LABEL: @nophi(207; CHECK-NEXT:  entry:208; CHECK-NEXT:    [[INCDEC_PTR:%.*]] = getelementptr inbounds i32, ptr [[P:%.*]], i64 1209; CHECK-NEXT:    [[INITOP:%.*]] = load i32, ptr [[INCDEC_PTR]], align 4210; CHECK-NEXT:    switch i32 [[INITOP]], label [[EXIT:%.*]] [211; CHECK-NEXT:    i32 0, label [[BB0:%.*]]212; CHECK-NEXT:    i32 1, label [[BB1:%.*]]213; CHECK-NEXT:    ]214; CHECK:       bb0:215; CHECK-NEXT:    tail call void @use(i32 0)216; CHECK-NEXT:    br label [[INDIRECTGOTO:%.*]]217; CHECK:       bb1:218; CHECK-NEXT:    tail call void @use(i32 1)219; CHECK-NEXT:    br label [[INDIRECTGOTO]]220; CHECK:       indirectgoto:221; CHECK-NEXT:    [[SUNKADDR:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 4222; CHECK-NEXT:    [[NEWP:%.*]] = load i32, ptr [[SUNKADDR]], align 4223; CHECK-NEXT:    [[IDX:%.*]] = sext i32 [[NEWP]] to i64224; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x ptr], ptr @nophi.targets, i64 0, i64 [[IDX]]225; CHECK-NEXT:    [[NEWOP:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8226; CHECK-NEXT:    indirectbr ptr [[NEWOP]], [label [[BB0]], label %bb1]227; CHECK:       exit:228; CHECK-NEXT:    ret void229;230entry:231  %incdec.ptr = getelementptr inbounds i32, ptr %p, i64 1232  %initop = load i32, ptr %incdec.ptr, align 4233  switch i32 %initop, label %exit [234  i32 0, label %bb0235  i32 1, label %bb1236  ]237 238bb0:239  tail call void @use(i32 0)  br label %indirectgoto240 241bb1:242  tail call void @use(i32 1)243  br label %indirectgoto244 245indirectgoto:246  %newp = load i32, ptr %incdec.ptr, align 4247  %idx = sext i32 %newp to i64248  %arrayidx = getelementptr inbounds [2 x ptr], ptr @nophi.targets, i64 0, i64 %idx249  %newop = load ptr, ptr %arrayidx, align 8250  indirectbr ptr %newop, [label %bb0, label %bb1]251 252exit:253  ret void254}255 256; Don't do anything if the edge isn't critical.257define i32 @noncritical(i32 %k, ptr %p)258; CHECK-LABEL: @noncritical(259; CHECK-NEXT:  entry:260; CHECK-NEXT:    [[D:%.*]] = add i32 [[K:%.*]], 1261; CHECK-NEXT:    indirectbr ptr [[P:%.*]], [label [[BB0:%.*]], label %bb1]262; CHECK:       bb0:263; CHECK-NEXT:    [[R0:%.*]] = sub i32 [[K]], [[D]]264; CHECK-NEXT:    br label [[EXIT:%.*]]265; CHECK:       bb1:266; CHECK-NEXT:    [[R1:%.*]] = sub i32 [[D]], [[K]]267; CHECK-NEXT:    br label [[EXIT]]268; CHECK:       exit:269; CHECK-NEXT:    [[V:%.*]] = phi i32 [ [[R0]], [[BB0]] ], [ [[R1]], [[BB1:%.*]] ]270; CHECK-NEXT:    ret i32 [[V]]271;272{273entry:274  %d = add i32 %k, 1275  indirectbr ptr %p, [label %bb0, label %bb1]276 277bb0:278  %v00 = phi i32 [%k, %entry]279  %v01 = phi i32 [%d, %entry]280  %r0 = sub i32 %v00, %v01281  br label %exit282 283bb1:284  %v10 = phi i32 [%d, %entry]285  %v11 = phi i32 [%k, %entry]286  %r1 = sub i32 %v10, %v11287  br label %exit288 289exit:290  %v = phi i32 [%r0, %bb0], [%r1, %bb1]291  ret i32 %v292}293