brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.4 KiB · f6b62dc Raw
452 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -passes=flatten-cfg -S < %s | FileCheck %s3 4 5; This test checks whether the pass completes without a crash.6; The code is not transformed in any way7define void @test_not_crash(i32 %in_a) #0 {8; CHECK-LABEL: define void @test_not_crash9; CHECK-SAME: (i32 [[IN_A:%.*]]) {10; CHECK-NEXT:  entry:11; CHECK-NEXT:    [[CMP0:%.*]] = icmp eq i32 [[IN_A]], -112; CHECK-NEXT:    [[CMP1:%.*]] = icmp ne i32 [[IN_A]], 013; CHECK-NEXT:    [[COND0:%.*]] = and i1 [[CMP0]], [[CMP1]]14; CHECK-NEXT:    br i1 [[COND0]], label [[B0:%.*]], label [[B1:%.*]]15; CHECK:       b0:16; CHECK-NEXT:    [[CMP2:%.*]] = icmp eq i32 [[IN_A]], 017; CHECK-NEXT:    [[CMP3:%.*]] = icmp ne i32 [[IN_A]], 118; CHECK-NEXT:    [[COND1:%.*]] = or i1 [[CMP2]], [[CMP3]]19; CHECK-NEXT:    br i1 [[COND1]], label [[EXIT:%.*]], label [[B1]]20; CHECK:       b1:21; CHECK-NEXT:    br label [[EXIT]]22; CHECK:       exit:23; CHECK-NEXT:    ret void24;25entry:26  %cmp0 = icmp eq i32 %in_a, -127  %cmp1 = icmp ne i32 %in_a, 028  %cond0 = and i1 %cmp0, %cmp129  br i1 %cond0, label %b0, label %b130 31b0:                                ; preds = %entry32  %cmp2 = icmp eq i32 %in_a, 033  %cmp3 = icmp ne i32 %in_a, 134  %cond1 = or i1 %cmp2, %cmp335  br i1 %cond1, label %exit, label %b136 37b1:                                       ; preds = %entry, %b038  br label %exit39 40exit:                               ; preds = %entry, %b0, %b141  ret void42}43 44define void @test_not_crash2(float %a, float %b) #0 {45; CHECK-LABEL: define void @test_not_crash246; CHECK-SAME: (float [[A:%.*]], float [[B:%.*]]) {47; CHECK-NEXT:  entry:48; CHECK-NEXT:    [[TMP0:%.*]] = fcmp ult float [[A]], 1.000000e+0049; CHECK-NEXT:    [[TMP1:%.*]] = fcmp ult float [[B]], 1.000000e+0050; CHECK-NEXT:    [[TMP2:%.*]] = and i1 [[TMP0]], [[TMP1]]51; CHECK-NEXT:    br i1 [[TMP2]], label [[BB4:%.*]], label [[BB3:%.*]]52; CHECK:       bb3:53; CHECK-NEXT:    br label [[BB4]]54; CHECK:       bb4:55; CHECK-NEXT:    ret void56;57entry:58  %0 = fcmp ult float %a, 1.000000e+0059  br i1 %0, label %bb0, label %bb160 61bb3:                                               ; preds = %bb062  br label %bb463 64bb4:                                               ; preds = %bb0, %bb365  ret void66 67bb1:                                               ; preds = %entry68  br label %bb069 70bb0:                                               ; preds = %bb1, %entry71  %1 = fcmp ult float %b, 1.000000e+0072  br i1 %1, label %bb4, label %bb373}74 75define void @test_not_crash3(i32 %a) #0 {76; CHECK-LABEL: define void @test_not_crash377; CHECK-SAME: (i32 [[A:%.*]]) {78; CHECK-NEXT:  entry:79; CHECK-NEXT:    [[A_EQ_0:%.*]] = icmp eq i32 [[A]], 080; CHECK-NEXT:    br i1 [[A_EQ_0]], label [[BB0:%.*]], label [[BB1:%.*]]81; CHECK:       bb0:82; CHECK-NEXT:    br label [[BB1]]83; CHECK:       bb1:84; CHECK-NEXT:    [[A_EQ_1:%.*]] = icmp eq i32 [[A]], 185; CHECK-NEXT:    br i1 [[A_EQ_1]], label [[BB2:%.*]], label [[BB3:%.*]]86; CHECK:       bb2:87; CHECK-NEXT:    br label [[BB3]]88; CHECK:       bb3:89; CHECK-NEXT:    [[CHECK_BADREF:%.*]] = phi i32 [ 17, [[BB1]] ], [ 11, [[BB2]] ]90; CHECK-NEXT:    ret void91;92entry:93  %a_eq_0 = icmp eq i32 %a, 094  br i1 %a_eq_0, label %bb0, label %bb195 96bb0:                                              ; preds = %entry97  br label %bb198 99bb1:                                              ; preds = %bb0, %entry100  %a_eq_1 = icmp eq i32 %a, 1101  br i1 %a_eq_1, label %bb2, label %bb3102 103bb2:                                              ; preds = %bb1104  br label %bb3105 106bb3:                                              ; preds = %bb2, %bb1107  %check_badref = phi i32 [ 17, %bb1 ], [ 11, %bb2 ]108  ret void109}110 111 112@g = global i32 0, align 4113 114define void @test_then(i32 %x, i32 %y, i32 %z) {115; CHECK-LABEL: define void @test_then116; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {117; CHECK-NEXT:  entry.x:118; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ne i32 [[X]], 0119; CHECK-NEXT:    [[CMP_Y:%.*]] = icmp ne i32 [[Y]], 0120; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[CMP_X]], [[CMP_Y]]121; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_THEN_Y:%.*]], label [[EXIT:%.*]]122; CHECK:       if.then.y:123; CHECK-NEXT:    store i32 [[Z]], ptr @g, align 4124; CHECK-NEXT:    br label [[EXIT]]125; CHECK:       exit:126; CHECK-NEXT:    ret void127;128entry.x:129  %cmp.x = icmp ne i32 %x, 0130  br i1 %cmp.x, label %if.then.x, label %entry.y131 132if.then.x:133  store i32 %z, ptr @g, align 4134  br label %entry.y135 136entry.y:137  %cmp.y = icmp ne i32 %y, 0138  br i1 %cmp.y, label %if.then.y, label %exit139 140if.then.y:141  store i32 %z, ptr @g, align 4142  br label %exit143 144exit:145  ret void146}147 148define void @test_else(i32 %x, i32 %y, i32 %z) {149; CHECK-LABEL: define void @test_else150; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {151; CHECK-NEXT:  entry.x:152; CHECK-NEXT:    [[CMP_X:%.*]] = icmp eq i32 [[X]], 0153; CHECK-NEXT:    [[CMP_Y:%.*]] = icmp eq i32 [[Y]], 0154; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[CMP_X]], [[CMP_Y]]155; CHECK-NEXT:    br i1 [[TMP0]], label [[EXIT:%.*]], label [[IF_ELSE_Y:%.*]]156; CHECK:       if.else.y:157; CHECK-NEXT:    store i32 [[Z]], ptr @g, align 4158; CHECK-NEXT:    br label [[EXIT]]159; CHECK:       exit:160; CHECK-NEXT:    ret void161;162entry.x:163  %cmp.x = icmp eq i32 %x, 0164  br i1 %cmp.x, label %entry.y, label %if.else.x165 166if.else.x:167  store i32 %z, ptr @g, align 4168  br label %entry.y169 170entry.y:171  %cmp.y = icmp eq i32 %y, 0172  br i1 %cmp.y, label %exit, label %if.else.y173 174if.else.y:175  store i32 %z, ptr @g, align 4176  br label %exit177 178exit:179  ret void180}181 182define void @test_combine_and(i32 %x, i32 %y, i32 %z) {183; CHECK-LABEL: define void @test_combine_and184; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {185; CHECK-NEXT:  entry.x:186; CHECK-NEXT:    [[CMP_X:%.*]] = icmp eq i32 [[X]], 0187; CHECK-NEXT:    [[CMP_Y:%.*]] = icmp eq i32 [[Y]], 0188; CHECK-NEXT:    [[TMP0:%.*]] = and i1 [[CMP_X]], [[CMP_Y]]189; CHECK-NEXT:    br i1 [[TMP0]], label [[EXIT:%.*]], label [[IF_THEN_Y:%.*]]190; CHECK:       if.then.y:191; CHECK-NEXT:    store i32 [[Z]], ptr @g, align 4192; CHECK-NEXT:    br label [[EXIT]]193; CHECK:       exit:194; CHECK-NEXT:    ret void195;196entry.x:197  %cmp.x = icmp eq i32 %x, 0198  br i1 %cmp.x, label %entry.y, label %if.else.x199 200if.else.x:201  store i32 %z, ptr @g, align 4202  br label %entry.y203 204entry.y:205  %cmp.y = icmp ne i32 %y, 0206  br i1 %cmp.y, label %if.then.y, label %exit207 208if.then.y:209  store i32 %z, ptr @g, align 4210  br label %exit211 212exit:213  ret void214}215 216define void @test_combine_or(i32 %x, i32 %y, i32 %z) {217; CHECK-LABEL: define void @test_combine_or218; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {219; CHECK-NEXT:  entry.x:220; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ne i32 [[X]], 0221; CHECK-NEXT:    [[CMP_Y:%.*]] = icmp ne i32 [[Y]], 0222; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[CMP_X]], [[CMP_Y]]223; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_ELSE_Y:%.*]], label [[EXIT:%.*]]224; CHECK:       if.else.y:225; CHECK-NEXT:    store i32 [[Z]], ptr @g, align 4226; CHECK-NEXT:    br label [[EXIT]]227; CHECK:       exit:228; CHECK-NEXT:    ret void229;230entry.x:231  %cmp.x = icmp ne i32 %x, 0232  br i1 %cmp.x, label %if.then.x, label %entry.y233 234if.then.x:235  store i32 %z, ptr @g, align 4236  br label %entry.y237 238entry.y:239  %cmp.y = icmp eq i32 %y, 0240  br i1 %cmp.y, label %exit, label %if.else.y241 242if.else.y:243  store i32 %z, ptr @g, align 4244  br label %exit245 246exit:247  ret void248}249 250declare i1 @llvm.smax.i1(i1, i1) #0251 252define void @PR56875(i1 %val_i1_5) {253; CHECK-LABEL: define void @PR56875254; CHECK-SAME: (i1 [[VAL_I1_5:%.*]]) {255; CHECK-NEXT:  entry_1:256; CHECK-NEXT:    ret void257; CHECK:       bb_2:258; CHECK-NEXT:    br label [[BB_4:%.*]]259; CHECK:       bb_4:260; CHECK-NEXT:    [[VAL_I1_46:%.*]] = call i1 @llvm.smax.i1(i1 [[VAL_I1_5]], i1 [[VAL_I1_5]])261; CHECK-NEXT:    br i1 [[VAL_I1_46]], label [[BB_4]], label [[BB_2:%.*]]262;263entry_1:264  ret void265 266bb_2:                                             ; preds = %bb_4267  br label %bb_4268 269bb_4:                                             ; preds = %bb_4, %bb_2270  %val_i1_46 = call i1 @llvm.smax.i1(i1 %val_i1_5, i1 %val_i1_5)271  br i1 %val_i1_46, label %bb_4, label %bb_2272}273 274; cmp.y has 2 users, but should be inverted. So that a new one cmp is created instead.275; Branch condition must be replaced with a new created combined condition276; Proof of bug: https://alive2.llvm.org/ce/z/L4ps9v277; Proof of fix: https://alive2.llvm.org/ce/z/QdrG5U278define i1 @test_cond_multi_use(i32 %x, i32 %y, i32 %z) {279; CHECK-LABEL: define i1 @test_cond_multi_use280; CHECK-SAME: (i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {281; CHECK-NEXT:  entry.x:282; CHECK-NEXT:    [[CMP_X:%.*]] = icmp ne i32 [[X]], 0283; CHECK-NEXT:    [[CMP_Y:%.*]] = icmp eq i32 [[Y]], 0284; CHECK-NEXT:    [[CMP_Y_NOT:%.*]] = xor i1 [[CMP_Y]], true285; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[CMP_X]], [[CMP_Y_NOT]]286; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_THEN_Y:%.*]], label [[EXIT:%.*]]287; CHECK:       if.then.y:288; CHECK-NEXT:    store i32 [[Z]], ptr @g, align 4289; CHECK-NEXT:    br label [[EXIT]]290; CHECK:       exit:291; CHECK-NEXT:    ret i1 [[CMP_Y]]292;293entry.x:294  %cmp.x = icmp ne i32 %x, 0295  br i1 %cmp.x, label %if.then.x, label %entry.y296 297if.then.x:298  store i32 %z, ptr @g, align 4299  br label %entry.y300 301entry.y:302  %cmp.y = icmp eq i32 %y, 0303  br i1 %cmp.y, label %exit, label %if.then.y304 305if.then.y:306  store i32 %z, ptr @g, align 4307  br label %exit308 309exit:310  ret i1 %cmp.y311}312 313declare void @foo()314declare void @bar() #1315 316; Test that two if-regions are not merged when there's potential aliasing317; between a store in the first if-region and a load in the second if-region's header318define i32 @test_alias(i32 %a, i32 %b, ptr %p1, ptr %p2) {319; CHECK-LABEL: define i32 @test_alias320; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]], ptr [[P1:%.*]], ptr [[P2:%.*]]) {321; CHECK-NEXT:  entry:322; CHECK-NEXT:    store i32 42, ptr [[P1]], align 4323; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i32 [[A]], 0324; CHECK-NEXT:    br i1 [[COND1]], label [[IF_THEN1:%.*]], label [[IF_END1:%.*]]325; CHECK:       if.then1:326; CHECK-NEXT:    store i32 100, ptr [[P2]], align 4327; CHECK-NEXT:    br label [[IF_END1]]328; CHECK:       if.end1:329; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr [[P1]], align 4330; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i32 [[B]], 0331; CHECK-NEXT:    br i1 [[COND2]], label [[IF_THEN2:%.*]], label [[IF_END2:%.*]]332; CHECK:       if.then2:333; CHECK-NEXT:    store i32 100, ptr [[P2]], align 4334; CHECK-NEXT:    br label [[IF_END2]]335; CHECK:       if.end2:336; CHECK-NEXT:    ret i32 0337;338entry:339  store i32 42, ptr %p1340  %cond1 = icmp eq i32 %a, 0341  br i1 %cond1, label %if.then1, label %if.end1342 343if.then1:344  store i32 100, ptr %p2  ; May alias with the load below345  br label %if.end1346 347if.end1:348  %val = load i32, ptr %p1  ; This load prevents merging due to potential alias349  %cond2 = icmp eq i32 %b, 0350  br i1 %cond2, label %if.then2, label %if.end2351 352if.then2:353  store i32 100, ptr %p2354  br label %if.end2355 356if.end2:357  ret i32 0358}359 360; Test that two if-regions are not merged when there's potential aliasing361; between a store in the first if-region and a function call in the second if-region's header362define i32 @test_alias_2(i32 %a, i32 %b) {363; CHECK-LABEL: define i32 @test_alias_2364; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {365; CHECK-NEXT:  entry:366; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4367; CHECK-NEXT:    store i32 42, ptr [[P]], align 4368; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i32 [[A]], 0369; CHECK-NEXT:    br i1 [[COND1]], label [[IF_THEN1:%.*]], label [[IF_END1:%.*]]370; CHECK:       if.then1:371; CHECK-NEXT:    store i32 100, ptr @g, align 4372; CHECK-NEXT:    br label [[IF_END1]]373; CHECK:       if.end1:374; CHECK-NEXT:    call void @foo()375; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i32 [[B]], 0376; CHECK-NEXT:    br i1 [[COND2]], label [[IF_THEN2:%.*]], label [[IF_END2:%.*]]377; CHECK:       if.then2:378; CHECK-NEXT:    store i32 100, ptr @g, align 4379; CHECK-NEXT:    br label [[IF_END2]]380; CHECK:       if.end2:381; CHECK-NEXT:    ret i32 0382;383entry:384  %p = alloca i32385  store i32 42, ptr %p386  %cond1 = icmp eq i32 %a, 0387  br i1 %cond1, label %if.then1, label %if.end1388 389if.then1:390  store i32 100, ptr @g391  br label %if.end1392 393if.end1:394  call void @foo()395  %cond2 = icmp eq i32 %b, 0396  br i1 %cond2, label %if.then2, label %if.end2397 398if.then2:399  store i32 100, ptr @g400  br label %if.end2401 402if.end2:403  ret i32 0404}405 406; Test that two if-regions are merged when there's no potential aliasing407; between a store in the first if-region and a load in the second if-region's header408define i32 @test_no_alias(i32 %a, i32 %b) {409; CHECK-LABEL: define i32 @test_no_alias410; CHECK-SAME: (i32 [[A:%.*]], i32 [[B:%.*]]) {411; CHECK-NEXT:  entry:412; CHECK-NEXT:    [[P:%.*]] = alloca i32, align 4413; CHECK-NEXT:    store i32 42, ptr [[P]], align 4414; CHECK-NEXT:    [[COND1:%.*]] = icmp eq i32 [[A]], 0415; CHECK-NEXT:    [[VAL:%.*]] = load i32, ptr @g, align 4416; CHECK-NEXT:    [[COND2:%.*]] = icmp eq i32 [[B]], 0417; CHECK-NEXT:    [[TMP0:%.*]] = or i1 [[COND1]], [[COND2]]418; CHECK-NEXT:    br i1 [[TMP0]], label [[IF_THEN2:%.*]], label [[IF_END2:%.*]]419; CHECK:       if.then2:420; CHECK-NEXT:    store i32 100, ptr [[P]], align 4421; CHECK-NEXT:    call void @bar()422; CHECK-NEXT:    br label [[IF_END2]]423; CHECK:       if.end2:424; CHECK-NEXT:    ret i32 0425;426entry:427  %p = alloca i32428  store i32 42, ptr %p429  %cond1 = icmp eq i32 %a, 0430  br i1 %cond1, label %if.then1, label %if.end1431 432if.then1:433  store i32 100, ptr %p  ; No alias with the load below434  call void @bar() ; No alias with the load below since it's a pure function435  br label %if.end1436 437if.end1:438  %val = load i32, ptr @g439  %cond2 = icmp eq i32 %b, 0440  br i1 %cond2, label %if.then2, label %if.end2441 442if.then2:443  store i32 100, ptr %p444  call void @bar()445  br label %if.end2446 447if.end2:448  ret i32 0449}450 451attributes #1 = { readnone willreturn nounwind }452