brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.9 KiB · 07486ff Raw
427 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes='instcombine<no-verify-fixpoint>' -S  < %s | FileCheck %s3 4; In many of these tests nuw can be inferred on the sunk GEP in the exit5; block. However, the condition is only converted into the necessary form6; after it has been sunk and revisited already.7 8target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:64"9 10define ptr@test1(ptr %A, i32 %Offset) {11; CHECK-LABEL: @test1(12; CHECK-NEXT:  entry:13; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 214; CHECK-NEXT:    br label [[BB:%.*]]15; CHECK:       bb:16; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]17; CHECK-NEXT:    [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 418; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 40019; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]20; CHECK:       bb2:21; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i32 [[RHS_IDX]]22; CHECK-NEXT:    ret ptr [[RHS_PTR]]23;24entry:25  %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset26  br label %bb27 28bb:29  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]30  %LHS = getelementptr inbounds i32, ptr %A, i32 10031  %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 132  %cond = icmp ult ptr %LHS, %RHS33  br i1 %cond, label %bb2, label %bb34 35bb2:36  ret ptr %RHS37}38 39define ptr @test1_nuw(ptr %A, i32 %Offset) {40; CHECK-LABEL: @test1_nuw(41; CHECK-NEXT:  entry:42; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nuw nsw i32 [[OFFSET:%.*]], 243; CHECK-NEXT:    br label [[BB:%.*]]44; CHECK:       bb:45; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]46; CHECK-NEXT:    [[RHS_ADD]] = add nuw nsw i32 [[RHS_IDX]], 447; CHECK-NEXT:    [[COND:%.*]] = icmp samesign ugt i32 [[RHS_IDX]], 40048; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]49; CHECK:       bb2:50; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds nuw i8, ptr [[A:%.*]], i32 [[RHS_IDX]]51; CHECK-NEXT:    ret ptr [[RHS_PTR]]52;53entry:54  %tmp = getelementptr inbounds nuw i32, ptr %A, i32 %Offset55  br label %bb56 57bb:58  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]59  %LHS = getelementptr inbounds nuw i32, ptr %A, i32 10060  %RHS.next = getelementptr inbounds nuw i32, ptr %RHS, i64 161  %cond = icmp ult ptr %LHS, %RHS62  br i1 %cond, label %bb2, label %bb63 64bb2:65  ret ptr %RHS66}67 68define ptr @test1_not_all_nuw(ptr %A, i32 %Offset) {69; CHECK-LABEL: @test1_not_all_nuw(70; CHECK-NEXT:  entry:71; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 272; CHECK-NEXT:    br label [[BB:%.*]]73; CHECK:       bb:74; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]75; CHECK-NEXT:    [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 476; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 40077; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]78; CHECK:       bb2:79; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A:%.*]], i32 [[RHS_IDX]]80; CHECK-NEXT:    ret ptr [[RHS_PTR]]81;82entry:83  %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset84  br label %bb85 86bb:87  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]88  %LHS = getelementptr inbounds nuw i32, ptr %A, i32 10089  %RHS.next = getelementptr inbounds nuw i32, ptr %RHS, i64 190  %cond = icmp ult ptr %LHS, %RHS91  br i1 %cond, label %bb2, label %bb92 93bb2:94  ret ptr %RHS95}96 97define ptr@test2(i32 %A, i32 %Offset) {98; CHECK-LABEL: @test2(99; CHECK-NEXT:  entry:100; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2101; CHECK-NEXT:    br label [[BB:%.*]]102; CHECK:       bb:103; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]104; CHECK-NEXT:    [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4105; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400106; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]107; CHECK:       bb2:108; CHECK-NEXT:    [[A_PTR:%.*]] = inttoptr i32 [[A:%.*]] to ptr109; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A_PTR]], i32 [[RHS_IDX]]110; CHECK-NEXT:    ret ptr [[RHS_PTR]]111;112entry:113  %A.ptr = inttoptr i32 %A to ptr114  %tmp = getelementptr inbounds i32, ptr %A.ptr, i32 %Offset115  br label %bb116 117bb:118  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]119  %LHS = getelementptr inbounds i32, ptr %A.ptr, i32 100120  %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1121  %cmp0 = ptrtoint ptr %LHS to i32122  %cmp1 = ptrtoint ptr %RHS to i32123  %cond = icmp ult i32 %cmp0, %cmp1124  br i1 %cond, label %bb2, label %bb125 126bb2:127  ret ptr %RHS128}129 130; Perform the transformation only if we know that the GEPs used are inbounds.131define ptr @test3_no_inbounds1(ptr %A, i32 %Offset) {132; CHECK-LABEL: @test3_no_inbounds1(133; CHECK-NEXT:  entry:134; CHECK-NEXT:    [[TMP:%.*]] = getelementptr i32, ptr [[A:%.*]], i32 [[OFFSET:%.*]]135; CHECK-NEXT:    br label [[BB:%.*]]136; CHECK:       bb:137; CHECK-NEXT:    [[RHS:%.*]] = phi ptr [ [[RHS_NEXT:%.*]], [[BB]] ], [ [[TMP]], [[ENTRY:%.*]] ]138; CHECK-NEXT:    [[LHS:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 400139; CHECK-NEXT:    [[RHS_NEXT]] = getelementptr inbounds nuw i8, ptr [[RHS]], i32 4140; CHECK-NEXT:    [[COND:%.*]] = icmp ult ptr [[LHS]], [[RHS]]141; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]142; CHECK:       bb2:143; CHECK-NEXT:    ret ptr [[RHS]]144;145entry:146  %tmp = getelementptr i32, ptr %A, i32 %Offset147  br label %bb148 149bb:150  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]151  %LHS = getelementptr inbounds i32, ptr %A, i32 100152  %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1153  %cond = icmp ult ptr %LHS, %RHS154  br i1 %cond, label %bb2, label %bb155 156bb2:157  ret ptr %RHS158}159 160define ptr @test3_no_inbounds2(ptr %A, i32 %Offset) {161; CHECK-LABEL: @test3_no_inbounds2(162; CHECK-NEXT:  entry:163; CHECK-NEXT:    [[TMP:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[OFFSET:%.*]]164; CHECK-NEXT:    br label [[BB:%.*]]165; CHECK:       bb:166; CHECK-NEXT:    [[RHS:%.*]] = phi ptr [ [[RHS_NEXT:%.*]], [[BB]] ], [ [[TMP]], [[ENTRY:%.*]] ]167; CHECK-NEXT:    [[LHS:%.*]] = getelementptr inbounds nuw i8, ptr [[A]], i32 400168; CHECK-NEXT:    [[RHS_NEXT]] = getelementptr i8, ptr [[RHS]], i32 4169; CHECK-NEXT:    [[COND:%.*]] = icmp ult ptr [[LHS]], [[RHS]]170; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]171; CHECK:       bb2:172; CHECK-NEXT:    ret ptr [[RHS]]173;174entry:175  %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset176  br label %bb177 178bb:179  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]180  %LHS = getelementptr inbounds i32, ptr %A, i32 100181  %RHS.next = getelementptr i32, ptr %RHS, i64 1182  %cond = icmp ult ptr %LHS, %RHS183  br i1 %cond, label %bb2, label %bb184 185bb2:186  ret ptr %RHS187}188 189define ptr @test3_no_inbounds3(ptr %A, i32 %Offset) {190; CHECK-LABEL: @test3_no_inbounds3(191; CHECK-NEXT:  entry:192; CHECK-NEXT:    [[TMP:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i32 [[OFFSET:%.*]]193; CHECK-NEXT:    br label [[BB:%.*]]194; CHECK:       bb:195; CHECK-NEXT:    [[RHS:%.*]] = phi ptr [ [[RHS_NEXT:%.*]], [[BB]] ], [ [[TMP]], [[ENTRY:%.*]] ]196; CHECK-NEXT:    [[LHS:%.*]] = getelementptr i8, ptr [[A]], i32 400197; CHECK-NEXT:    [[RHS_NEXT]] = getelementptr inbounds nuw i8, ptr [[RHS]], i32 4198; CHECK-NEXT:    [[COND:%.*]] = icmp ult ptr [[LHS]], [[RHS]]199; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]200; CHECK:       bb2:201; CHECK-NEXT:    ret ptr [[RHS]]202;203entry:204  %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset205  br label %bb206 207bb:208  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]209  %LHS = getelementptr i32, ptr %A, i32 100210  %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1211  %cond = icmp ult ptr %LHS, %RHS212  br i1 %cond, label %bb2, label %bb213 214bb2:215  ret ptr %RHS216}217 218; An inttoptr that requires an extension or truncation will be opaque when determining219; the base pointer. In this case we can still perform the transformation by considering220; A.ptr as being the base pointer.221define ptr@test4(i16 %A, i32 %Offset) {222; CHECK-LABEL: @test4(223; CHECK-NEXT:  entry:224; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2225; CHECK-NEXT:    br label [[BB:%.*]]226; CHECK:       bb:227; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[ENTRY:%.*]] ]228; CHECK-NEXT:    [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4229; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400230; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]231; CHECK:       bb2:232; CHECK-NEXT:    [[TMP0:%.*]] = zext i16 [[A:%.*]] to i32233; CHECK-NEXT:    [[A_PTR:%.*]] = inttoptr i32 [[TMP0]] to ptr234; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A_PTR]], i32 [[RHS_IDX]]235; CHECK-NEXT:    ret ptr [[RHS_PTR]]236;237entry:238  %A.ptr = inttoptr i16 %A to ptr239  %tmp = getelementptr inbounds i32, ptr %A.ptr, i32 %Offset240  br label %bb241 242bb:243  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %entry ]244  %LHS = getelementptr inbounds i32, ptr %A.ptr, i32 100245  %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1246  %cmp0 = ptrtoint ptr %LHS to i32247  %cmp1 = ptrtoint ptr %RHS to i32248  %cond = icmp ult i32 %cmp0, %cmp1249  br i1 %cond, label %bb2, label %bb250 251bb2:252  ret ptr %RHS253}254 255declare ptr @fun_ptr()256 257define ptr@test5(i32 %Offset) personality ptr @__gxx_personality_v0 {258; CHECK-LABEL: @test5(259; CHECK-NEXT:  entry:260; CHECK-NEXT:    [[A:%.*]] = invoke ptr @fun_ptr()261; CHECK-NEXT:            to label [[CONT:%.*]] unwind label [[LPAD:%.*]]262; CHECK:       cont:263; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2264; CHECK-NEXT:    br label [[BB:%.*]]265; CHECK:       bb:266; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[CONT]] ]267; CHECK-NEXT:    [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4268; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400269; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]270; CHECK:       bb2:271; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A]], i32 [[RHS_IDX]]272; CHECK-NEXT:    ret ptr [[RHS_PTR]]273; CHECK:       lpad:274; CHECK-NEXT:    [[L:%.*]] = landingpad { ptr, i32 }275; CHECK-NEXT:            cleanup276; CHECK-NEXT:    ret ptr null277;278entry:279  %A = invoke ptr@fun_ptr() to label %cont unwind label %lpad280 281cont:282  %tmp = getelementptr inbounds i32, ptr %A, i32 %Offset283  br label %bb284 285bb:286  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %cont ]287  %LHS = getelementptr inbounds i32, ptr %A, i32 100288  %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1289  %cond = icmp ult ptr %LHS, %RHS290  br i1 %cond, label %bb2, label %bb291 292bb2:293  ret ptr %RHS294 295lpad:296  %l = landingpad { ptr, i32 } cleanup297  ret ptr null298}299 300declare i32 @fun_i32()301 302define ptr@test6(i32 %Offset) personality ptr @__gxx_personality_v0 {303; CHECK-LABEL: @test6(304; CHECK-NEXT:  entry:305; CHECK-NEXT:    [[A:%.*]] = invoke i32 @fun_i32()306; CHECK-NEXT:            to label [[CONT:%.*]] unwind label [[LPAD:%.*]]307; CHECK:       cont:308; CHECK-NEXT:    [[TMP_IDX:%.*]] = shl nsw i32 [[OFFSET:%.*]], 2309; CHECK-NEXT:    br label [[BB:%.*]]310; CHECK:       bb:311; CHECK-NEXT:    [[RHS_IDX:%.*]] = phi i32 [ [[RHS_ADD:%.*]], [[BB]] ], [ [[TMP_IDX]], [[CONT]] ]312; CHECK-NEXT:    [[RHS_ADD]] = add nsw i32 [[RHS_IDX]], 4313; CHECK-NEXT:    [[COND:%.*]] = icmp sgt i32 [[RHS_IDX]], 400314; CHECK-NEXT:    br i1 [[COND]], label [[BB2:%.*]], label [[BB]]315; CHECK:       bb2:316; CHECK-NEXT:    [[A_PTR:%.*]] = inttoptr i32 [[A]] to ptr317; CHECK-NEXT:    [[RHS_PTR:%.*]] = getelementptr inbounds i8, ptr [[A_PTR]], i32 [[RHS_IDX]]318; CHECK-NEXT:    ret ptr [[RHS_PTR]]319; CHECK:       lpad:320; CHECK-NEXT:    [[L:%.*]] = landingpad { ptr, i32 }321; CHECK-NEXT:            cleanup322; CHECK-NEXT:    ret ptr null323;324entry:325  %A = invoke i32 @fun_i32() to label %cont unwind label %lpad326 327cont:328  %A.ptr = inttoptr i32 %A to ptr329  %tmp = getelementptr inbounds i32, ptr %A.ptr, i32 %Offset330  br label %bb331 332bb:333  %RHS = phi ptr [ %RHS.next, %bb ], [ %tmp, %cont ]334  %LHS = getelementptr inbounds i32, ptr %A.ptr, i32 100335  %RHS.next = getelementptr inbounds i32, ptr %RHS, i64 1336  %cond = icmp ult ptr %LHS, %RHS337  br i1 %cond, label %bb2, label %bb338 339bb2:340  ret ptr %RHS341 342lpad:343  %l = landingpad { ptr, i32 } cleanup344  ret ptr null345}346 347 348@pr30402 = constant i64 3349define i1 @test7() {350; CHECK-LABEL: @test7(351; CHECK-NEXT:  entry:352; CHECK-NEXT:    br label [[BB7:%.*]]353; CHECK:       bb7:354; CHECK-NEXT:    [[CMP:%.*]] = phi i1 [ false, [[ENTRY:%.*]] ], [ true, [[BB7]] ]355; CHECK-NEXT:    br i1 [[CMP]], label [[BB10:%.*]], label [[BB7]]356; CHECK:       bb10:357; CHECK-NEXT:    ret i1 true358;359entry:360  br label %bb7361 362bb7:                                              ; preds = %bb10, %entry-block363  %phi = phi ptr [ @pr30402, %entry ], [ getelementptr inbounds (i64, ptr @pr30402, i32 1), %bb7 ]364  %cmp = icmp eq ptr %phi, getelementptr inbounds (i64, ptr @pr30402, i32 1)365  br i1 %cmp, label %bb10, label %bb7366 367bb10:368  ret i1 %cmp369}370 371declare i32 @__gxx_personality_v0(...)372 373define i1 @test8(ptr %in, i64 %offset) {374; CHECK-LABEL: @test8(375; CHECK-NEXT:  entry:376; CHECK-NEXT:    [[LD:%.*]] = load i64, ptr [[IN:%.*]], align 8377; CHECK-NEXT:    [[TMP0:%.*]] = trunc i64 [[LD]] to i32378; CHECK-NEXT:    [[CASTI8:%.*]] = inttoptr i32 [[TMP0]] to ptr379; CHECK-NEXT:    [[TMP1:%.*]] = trunc nsw i64 [[OFFSET:%.*]] to i32380; CHECK-NEXT:    [[GEPI8:%.*]] = getelementptr inbounds i8, ptr [[CASTI8]], i32 [[TMP1]]381; CHECK-NEXT:    [[TMP2:%.*]] = trunc i64 [[LD]] to i32382; CHECK-NEXT:    [[PTRCAST:%.*]] = inttoptr i32 [[TMP2]] to ptr383; CHECK-NEXT:    [[GEPI32:%.*]] = getelementptr inbounds nuw i8, ptr [[PTRCAST]], i32 4384; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[GEPI32]], [[GEPI8]]385; CHECK-NEXT:    ret i1 [[CMP]]386;387entry:388  %ld = load i64, ptr %in, align 8389  %casti8 = inttoptr i64 %ld to ptr390  %gepi8 = getelementptr inbounds i8, ptr %casti8, i64 %offset391  %ptrcast = inttoptr i64 %ld to ptr392  %gepi32 = getelementptr inbounds ptr, ptr %ptrcast, i64 1393  %cmp = icmp eq ptr %gepi32, %gepi8394  ret i1 %cmp395}396 397define void @test_zero_offset_cycle(ptr %arg) {398; CHECK-LABEL: @test_zero_offset_cycle(399; CHECK-NEXT:  entry:400; CHECK-NEXT:    [[GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[ARG:%.*]], i32 8401; CHECK-NEXT:    [[GEP_INT:%.*]] = ptrtoint ptr [[GEP]] to i32402; CHECK-NEXT:    br label [[LOOP:%.*]]403; CHECK:       loop:404; CHECK-NEXT:    [[PHI:%.*]] = phi i32 [ [[GEP_INT]], [[ENTRY:%.*]] ], [ [[GEP_INT2:%.*]], [[LOOP_CONT:%.*]] ], [ [[PHI]], [[LOOP]] ]405; CHECK-NEXT:    [[PHI_PTR:%.*]] = inttoptr i32 [[PHI]] to ptr406; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[GEP]], [[PHI_PTR]]407; CHECK-NEXT:    br i1 [[CMP]], label [[LOOP]], label [[LOOP_CONT]]408; CHECK:       loop.cont:409; CHECK-NEXT:    [[GEP_INT2]] = ptrtoint ptr [[GEP]] to i32410; CHECK-NEXT:    br label [[LOOP]]411;412entry:413  %gep = getelementptr inbounds { i64, i64 }, ptr %arg, i32 0, i32 1414  %gep.int = ptrtoint ptr %gep to i32415  br label %loop416 417loop:418  %phi = phi i32 [ %gep.int, %entry ], [ %gep.int2, %loop.cont ], [ %phi, %loop ]419  %phi.ptr = inttoptr i32 %phi to ptr420  %cmp = icmp eq ptr %gep, %phi.ptr421  br i1 %cmp, label %loop, label %loop.cont422 423loop.cont:424  %gep.int2 = ptrtoint ptr %gep to i32425  br label %loop426}427