brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.1 KiB · 65ecb87 Raw
314 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=licm -S < %s | FileCheck %s3; RUN: opt -passes='loop-mssa(licm)' -S %s | FileCheck %s4 5; If we can prove a local is thread local, we can insert stores during6; promotion which wouldn't be legal otherwise.7 8target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"9target triple = "x86_64-linux-generic"10 11@p = external global ptr12 13declare ptr @malloc(i64)14 15; Exercise the TLS case16define ptr @test(i32 %n) {17; CHECK-LABEL: @test(18; CHECK-NEXT:  entry:19; CHECK-NEXT:    [[MEM:%.*]] = call noalias dereferenceable(16) ptr @malloc(i64 16)20; CHECK-NEXT:    br label [[FOR_BODY_LR_PH:%.*]]21; CHECK:       for.body.lr.ph:22; CHECK-NEXT:    [[ADDR_PROMOTED:%.*]] = load i32, ptr [[MEM]], align 423; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]24; CHECK:       for.header:25; CHECK-NEXT:    [[NEW1:%.*]] = phi i32 [ [[ADDR_PROMOTED]], [[FOR_BODY_LR_PH]] ], [ [[NEW:%.*]], [[FOR_BODY:%.*]] ]26; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]27; CHECK-NEXT:    [[GUARD:%.*]] = load atomic ptr, ptr @p monotonic, align 828; CHECK-NEXT:    [[EXITCMP:%.*]] = icmp eq ptr [[GUARD]], null29; CHECK-NEXT:    br i1 [[EXITCMP]], label [[FOR_BODY]], label [[EARLY_EXIT:%.*]]30; CHECK:       early-exit:31; CHECK-NEXT:    [[NEW1_LCSSA:%.*]] = phi i32 [ [[NEW1]], [[FOR_HEADER]] ]32; CHECK-NEXT:    store i32 [[NEW1_LCSSA]], ptr [[MEM]], align 433; CHECK-NEXT:    ret ptr null34; CHECK:       for.body:35; CHECK-NEXT:    [[NEW]] = add i32 [[NEW1]], 136; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 137; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N:%.*]]38; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_HEADER]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]39; CHECK:       for.cond.for.end_crit_edge:40; CHECK-NEXT:    [[NEW_LCSSA:%.*]] = phi i32 [ [[NEW]], [[FOR_BODY]] ]41; CHECK-NEXT:    [[SPLIT:%.*]] = phi ptr [ [[MEM]], [[FOR_BODY]] ]42; CHECK-NEXT:    store i32 [[NEW_LCSSA]], ptr [[MEM]], align 443; CHECK-NEXT:    ret ptr null44;45entry:46  ;; ignore the required null check for simplicity47  %mem = call dereferenceable(16) noalias ptr @malloc(i64 16)48  br label %for.body.lr.ph49 50for.body.lr.ph:                                   ; preds = %entry51  br label %for.header52 53for.header:54  %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]55  %old = load i32, ptr %mem, align 456  ; deliberate impossible to analyze branch57  %guard = load atomic ptr, ptr @p monotonic, align 858  %exitcmp = icmp eq ptr %guard, null59  br i1 %exitcmp, label %for.body, label %early-exit60 61early-exit:62  ret ptr null63 64for.body:65  %new = add i32 %old, 166  store i32 %new, ptr %mem, align 467  %inc = add nsw i32 %i.02, 168  %cmp = icmp slt i32 %inc, %n69  br i1 %cmp, label %for.header, label %for.cond.for.end_crit_edge70 71for.cond.for.end_crit_edge:                       ; preds = %for.body72  %split = phi ptr [ %mem, %for.body ]73  ret ptr null74}75 76; Stack allocations can also be thread-local77define ptr @test2(i32 %n) {78; CHECK-LABEL: @test2(79; CHECK-NEXT:  entry:80; CHECK-NEXT:    [[MEM:%.*]] = alloca i8, i32 16, align 181; CHECK-NEXT:    br label [[FOR_BODY_LR_PH:%.*]]82; CHECK:       for.body.lr.ph:83; CHECK-NEXT:    [[ADDR_PROMOTED:%.*]] = load i32, ptr [[MEM]], align 484; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]85; CHECK:       for.header:86; CHECK-NEXT:    [[NEW1:%.*]] = phi i32 [ [[ADDR_PROMOTED]], [[FOR_BODY_LR_PH]] ], [ [[NEW:%.*]], [[FOR_BODY:%.*]] ]87; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]88; CHECK-NEXT:    [[GUARD:%.*]] = load atomic ptr, ptr @p monotonic, align 889; CHECK-NEXT:    [[EXITCMP:%.*]] = icmp eq ptr [[GUARD]], null90; CHECK-NEXT:    br i1 [[EXITCMP]], label [[FOR_BODY]], label [[EARLY_EXIT:%.*]]91; CHECK:       early-exit:92; CHECK-NEXT:    [[NEW1_LCSSA:%.*]] = phi i32 [ [[NEW1]], [[FOR_HEADER]] ]93; CHECK-NEXT:    store i32 [[NEW1_LCSSA]], ptr [[MEM]], align 494; CHECK-NEXT:    ret ptr null95; CHECK:       for.body:96; CHECK-NEXT:    [[NEW]] = add i32 [[NEW1]], 197; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 198; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N:%.*]]99; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_HEADER]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]100; CHECK:       for.cond.for.end_crit_edge:101; CHECK-NEXT:    [[NEW_LCSSA:%.*]] = phi i32 [ [[NEW]], [[FOR_BODY]] ]102; CHECK-NEXT:    [[SPLIT:%.*]] = phi ptr [ [[MEM]], [[FOR_BODY]] ]103; CHECK-NEXT:    store i32 [[NEW_LCSSA]], ptr [[MEM]], align 4104; CHECK-NEXT:    ret ptr null105;106entry:107  %mem = alloca i8, i32 16108  br label %for.body.lr.ph109 110for.body.lr.ph:                                   ; preds = %entry111  br label %for.header112 113for.header:114  %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]115  %old = load i32, ptr %mem, align 4116  ; deliberate impossible to analyze branch117  %guard = load atomic ptr, ptr @p monotonic, align 8118  %exitcmp = icmp eq ptr %guard, null119  br i1 %exitcmp, label %for.body, label %early-exit120 121early-exit:122  ret ptr null123 124for.body:125  %new = add i32 %old, 1126  store i32 %new, ptr %mem, align 4127  %inc = add nsw i32 %i.02, 1128  %cmp = icmp slt i32 %inc, %n129  br i1 %cmp, label %for.header, label %for.cond.for.end_crit_edge130 131for.cond.for.end_crit_edge:                       ; preds = %for.body132  %split = phi ptr [ %mem, %for.body ]133  ret ptr null134}135 136declare noalias ptr @custom_malloc(i64)137 138; Custom allocation function marked via noalias.139define ptr @test_custom_malloc(i32 %n) {140; CHECK-LABEL: @test_custom_malloc(141; CHECK-NEXT:  entry:142; CHECK-NEXT:    [[MEM:%.*]] = call noalias dereferenceable(16) ptr @custom_malloc(i64 16)143; CHECK-NEXT:    br label [[FOR_BODY_LR_PH:%.*]]144; CHECK:       for.body.lr.ph:145; CHECK-NEXT:    [[ADDR_PROMOTED:%.*]] = load i32, ptr [[MEM]], align 4146; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]147; CHECK:       for.header:148; CHECK-NEXT:    [[NEW1:%.*]] = phi i32 [ [[ADDR_PROMOTED]], [[FOR_BODY_LR_PH]] ], [ [[NEW:%.*]], [[FOR_BODY:%.*]] ]149; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]150; CHECK-NEXT:    [[GUARD:%.*]] = load volatile ptr, ptr @p, align 8151; CHECK-NEXT:    [[EXITCMP:%.*]] = icmp eq ptr [[GUARD]], null152; CHECK-NEXT:    br i1 [[EXITCMP]], label [[FOR_BODY]], label [[EARLY_EXIT:%.*]]153; CHECK:       early-exit:154; CHECK-NEXT:    [[NEW1_LCSSA:%.*]] = phi i32 [ [[NEW1]], [[FOR_HEADER]] ]155; CHECK-NEXT:    store i32 [[NEW1_LCSSA]], ptr [[MEM]], align 4156; CHECK-NEXT:    ret ptr null157; CHECK:       for.body:158; CHECK-NEXT:    [[NEW]] = add i32 [[NEW1]], 1159; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1160; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N:%.*]]161; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_HEADER]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]162; CHECK:       for.cond.for.end_crit_edge:163; CHECK-NEXT:    [[NEW_LCSSA:%.*]] = phi i32 [ [[NEW]], [[FOR_BODY]] ]164; CHECK-NEXT:    [[SPLIT:%.*]] = phi ptr [ [[MEM]], [[FOR_BODY]] ]165; CHECK-NEXT:    store i32 [[NEW_LCSSA]], ptr [[MEM]], align 4166; CHECK-NEXT:    ret ptr null167;168entry:169  %mem = call dereferenceable(16) noalias ptr @custom_malloc(i64 16)170  br label %for.body.lr.ph171 172for.body.lr.ph:                                   ; preds = %entry173  br label %for.header174 175for.header:176  %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]177  %old = load i32, ptr %mem, align 4178  ; deliberate impossible to analyze branch179  %guard = load volatile ptr, ptr @p180  %exitcmp = icmp eq ptr %guard, null181  br i1 %exitcmp, label %for.body, label %early-exit182 183early-exit:184  ret ptr null185 186for.body:187  %new = add i32 %old, 1188  store i32 %new, ptr %mem, align 4189  %inc = add nsw i32 %i.02, 1190  %cmp = icmp slt i32 %inc, %n191  br i1 %cmp, label %for.header, label %for.cond.for.end_crit_edge192 193for.cond.for.end_crit_edge:                       ; preds = %for.body194  %split = phi ptr [ %mem, %for.body ]195  ret ptr null196}197 198declare ptr @not_malloc(i64)199 200; Negative test - not an allocation function.201define ptr @test_neg_not_malloc(i32 %n) {202; CHECK-LABEL: @test_neg_not_malloc(203; CHECK-NEXT:  entry:204; CHECK-NEXT:    [[MEM:%.*]] = call dereferenceable(16) ptr @not_malloc(i64 16)205; CHECK-NEXT:    br label [[FOR_BODY_LR_PH:%.*]]206; CHECK:       for.body.lr.ph:207; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]208; CHECK:       for.header:209; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]210; CHECK-NEXT:    [[OLD:%.*]] = load i32, ptr [[MEM]], align 4211; CHECK-NEXT:    [[GUARD:%.*]] = load volatile ptr, ptr @p, align 8212; CHECK-NEXT:    [[EXITCMP:%.*]] = icmp eq ptr [[GUARD]], null213; CHECK-NEXT:    br i1 [[EXITCMP]], label [[FOR_BODY]], label [[EARLY_EXIT:%.*]]214; CHECK:       early-exit:215; CHECK-NEXT:    ret ptr null216; CHECK:       for.body:217; CHECK-NEXT:    [[NEW:%.*]] = add i32 [[OLD]], 1218; CHECK-NEXT:    store i32 [[NEW]], ptr [[MEM]], align 4219; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1220; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N:%.*]]221; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_HEADER]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]222; CHECK:       for.cond.for.end_crit_edge:223; CHECK-NEXT:    [[SPLIT:%.*]] = phi ptr [ [[MEM]], [[FOR_BODY]] ]224; CHECK-NEXT:    ret ptr null225;226entry:227  ;; ignore the required null check for simplicity228  %mem = call dereferenceable(16) ptr @not_malloc(i64 16)229  br label %for.body.lr.ph230 231for.body.lr.ph:                                   ; preds = %entry232  br label %for.header233 234for.header:235  %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]236  %old = load i32, ptr %mem, align 4237  ; deliberate impossible to analyze branch238  %guard = load volatile ptr, ptr @p239  %exitcmp = icmp eq ptr %guard, null240  br i1 %exitcmp, label %for.body, label %early-exit241 242early-exit:243  ret ptr null244 245for.body:246  %new = add i32 %old, 1247  store i32 %new, ptr %mem, align 4248  %inc = add nsw i32 %i.02, 1249  %cmp = icmp slt i32 %inc, %n250  br i1 %cmp, label %for.header, label %for.cond.for.end_crit_edge251 252for.cond.for.end_crit_edge:                       ; preds = %for.body253  %split = phi ptr [ %mem, %for.body ]254  ret ptr null255}256 257; Negative test - can't speculate load since branch258; may control alignment259define ptr @test_neg2(i32 %n) {260; CHECK-LABEL: @test_neg2(261; CHECK-NEXT:  entry:262; CHECK-NEXT:    [[MEM:%.*]] = call noalias dereferenceable(16) ptr @malloc(i64 16)263; CHECK-NEXT:    br label [[FOR_BODY_LR_PH:%.*]]264; CHECK:       for.body.lr.ph:265; CHECK-NEXT:    br label [[FOR_HEADER:%.*]]266; CHECK:       for.header:267; CHECK-NEXT:    [[I_02:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY:%.*]] ]268; CHECK-NEXT:    [[GUARD:%.*]] = load volatile ptr, ptr @p, align 8269; CHECK-NEXT:    [[EXITCMP:%.*]] = icmp eq ptr [[GUARD]], null270; CHECK-NEXT:    br i1 [[EXITCMP]], label [[FOR_BODY]], label [[EARLY_EXIT:%.*]]271; CHECK:       early-exit:272; CHECK-NEXT:    ret ptr null273; CHECK:       for.body:274; CHECK-NEXT:    [[OLD:%.*]] = load i32, ptr [[MEM]], align 4275; CHECK-NEXT:    [[NEW:%.*]] = add i32 [[OLD]], 1276; CHECK-NEXT:    store i32 [[NEW]], ptr [[MEM]], align 4277; CHECK-NEXT:    [[INC]] = add nsw i32 [[I_02]], 1278; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N:%.*]]279; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_HEADER]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]280; CHECK:       for.cond.for.end_crit_edge:281; CHECK-NEXT:    [[SPLIT:%.*]] = phi ptr [ [[MEM]], [[FOR_BODY]] ]282; CHECK-NEXT:    ret ptr null283;284entry:285  ;; ignore the required null check for simplicity286  %mem = call dereferenceable(16) noalias ptr @malloc(i64 16)287  br label %for.body.lr.ph288 289for.body.lr.ph:                                   ; preds = %entry290  br label %for.header291 292for.header:293  %i.02 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]294  ; deliberate impossible to analyze branch295  %guard = load volatile ptr, ptr @p296  %exitcmp = icmp eq ptr %guard, null297  br i1 %exitcmp, label %for.body, label %early-exit298 299early-exit:300  ret ptr null301 302for.body:303  %old = load i32, ptr %mem, align 4304  %new = add i32 %old, 1305  store i32 %new, ptr %mem, align 4306  %inc = add nsw i32 %i.02, 1307  %cmp = icmp slt i32 %inc, %n308  br i1 %cmp, label %for.header, label %for.cond.for.end_crit_edge309 310for.cond.for.end_crit_edge:                       ; preds = %for.body311  %split = phi ptr [ %mem, %for.body ]312  ret ptr null313}314