brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.3 KiB · 71332bf Raw
203 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; Test if the !invariant.load metadata is maintained by GVN.3; RUN: opt -passes=gvn -S < %s | FileCheck %s4 5define i32 @test1(ptr nocapture %p, ptr nocapture %q) {6; CHECK-LABEL: define i32 @test17; CHECK-SAME: (ptr captures(none) [[P:%.*]], ptr captures(none) [[Q:%.*]]) {8; CHECK-NEXT:  entry:9; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P]], align 4, !invariant.load [[META0:![0-9]+]]10; CHECK-NEXT:    [[CONV:%.*]] = trunc i32 [[X]] to i811; CHECK-NEXT:    store i8 [[CONV]], ptr [[Q]], align 112; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 113; CHECK-NEXT:    ret i32 [[ADD]]14;15entry:16  %x = load i32, ptr %p, align 4, !invariant.load !017  %conv = trunc i32 %x to i818  store i8 %conv, ptr %q, align 119  %y = load i32, ptr %p, align 4, !invariant.load !020  %add = add i32 %y, 121  ret i32 %add22}23 24define i32 @test2(ptr nocapture %p, ptr nocapture %q) {25; CHECK-LABEL: define i32 @test226; CHECK-SAME: (ptr captures(none) [[P:%.*]], ptr captures(none) [[Q:%.*]]) {27; CHECK-NEXT:  entry:28; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P]], align 429; CHECK-NEXT:    [[CONV:%.*]] = trunc i32 [[X]] to i830; CHECK-NEXT:    store i8 [[CONV]], ptr [[Q]], align 131; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], 132; CHECK-NEXT:    ret i32 [[ADD]]33;34entry:35  %x = load i32, ptr %p, align 436  %conv = trunc i32 %x to i837  store i8 %conv, ptr %q, align 138  %y = load i32, ptr %p, align 4, !invariant.load !039  %add = add i32 %y, 140  ret i32 %add41}42 43; With the invariant.load metadata, what would otherwise44; be a case for PRE becomes a full redundancy.45define i32 @test3(i1 %cnd, ptr %p, ptr %q) {46; CHECK-LABEL: define i32 @test347; CHECK-SAME: (i1 [[CND:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) {48; CHECK-NEXT:  entry:49; CHECK-NEXT:    br i1 [[CND]], label [[BB1:%.*]], label [[BB2:%.*]]50; CHECK:       bb1:51; CHECK-NEXT:    store i32 5, ptr [[Q]], align 452; CHECK-NEXT:    br label [[BB2]]53; CHECK:       bb2:54; CHECK-NEXT:    ret i32 055;56entry:57  %v1 = load i32, ptr %p58  br i1 %cnd, label %bb1, label %bb259 60bb1:61  store i32 5, ptr %q62  br label %bb263 64bb2:65  %v2 = load i32, ptr %p, !invariant.load !066  %res = sub i32 %v1, %v267  ret i32 %res68}69 70; This test is here to document a case which doesn't optimize71; as well as it could.72define i32 @test4(i1 %cnd, ptr %p, ptr %q) {73; CHECK-LABEL: define i32 @test474; CHECK-SAME: (i1 [[CND:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) {75; CHECK-NEXT:  entry:76; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[P]], align 4, !invariant.load [[META0]]77; CHECK-NEXT:    br i1 [[CND]], label [[BB1:%.*]], label [[BB2:%.*]]78; CHECK:       bb1:79; CHECK-NEXT:    store i32 5, ptr [[Q]], align 480; CHECK-NEXT:    [[V2_PRE:%.*]] = load i32, ptr [[P]], align 481; CHECK-NEXT:    br label [[BB2]]82; CHECK:       bb2:83; CHECK-NEXT:    [[V2:%.*]] = phi i32 [ [[V2_PRE]], [[BB1]] ], [ [[V1]], [[ENTRY:%.*]] ]84; CHECK-NEXT:    [[RES:%.*]] = sub i32 [[V1]], [[V2]]85; CHECK-NEXT:    ret i32 [[RES]]86;87; %v2 is redundant, but GVN currently doesn't catch that88entry:89  %v1 = load i32, ptr %p, !invariant.load !090  br i1 %cnd, label %bb1, label %bb291 92bb1:93  store i32 5, ptr %q94  br label %bb295 96bb2:97  %v2 = load i32, ptr %p98  %res = sub i32 %v1, %v299  ret i32 %res100}101 102; Checks that we return the mustalias store as a def103; so that it contributes to value forwarding.  Note104; that we could and should remove the store too.105define i32 @test5(i1 %cnd, ptr %p) {106; CHECK-LABEL: define i32 @test5107; CHECK-SAME: (i1 [[CND:%.*]], ptr [[P:%.*]]) {108; CHECK-NEXT:  entry:109; CHECK-NEXT:    store i32 5, ptr [[P]], align 4110; CHECK-NEXT:    ret i32 5111;112entry:113  %v1 = load i32, ptr %p, !invariant.load !0114  store i32 5, ptr %p ;; must alias store, want to exploit115  %v2 = load i32, ptr %p, !invariant.load !0116  ret i32 %v2117}118 119 120declare void @foo()121 122; Clobbering (mayalias) stores, even in function calls, can be ignored123define i32 @test6(i1 %cnd, ptr %p) {124; CHECK-LABEL: define i32 @test6125; CHECK-SAME: (i1 [[CND:%.*]], ptr [[P:%.*]]) {126; CHECK-NEXT:  entry:127; CHECK-NEXT:    call void @foo()128; CHECK-NEXT:    ret i32 0129;130entry:131  %v1 = load i32, ptr %p, !invariant.load !0132  call void @foo()133  %v2 = load i32, ptr %p, !invariant.load !0134  %res = sub i32 %v1, %v2135  ret i32 %res136}137 138declare noalias ptr @bar(...)139 140; Same as previous, but a function with a noalias result (since they're handled141; differently in MDA)142define i32 @test7(i1 %cnd, ptr %p) {143; CHECK-LABEL: define i32 @test7144; CHECK-SAME: (i1 [[CND:%.*]], ptr [[P:%.*]]) {145; CHECK-NEXT:  entry:146; CHECK-NEXT:    [[TMP0:%.*]] = call ptr (...) @bar(ptr [[P]])147; CHECK-NEXT:    ret i32 0148;149entry:150  %v1 = load i32, ptr %p, !invariant.load !0151  call ptr (...) @bar(ptr %p)152  %v2 = load i32, ptr %p, !invariant.load !0153  %res = sub i32 %v1, %v2154  ret i32 %res155}156 157define i32 @test8(i1 %cnd, ptr %p) {158; CHECK-LABEL: define i32 @test8159; CHECK-SAME: (i1 [[CND:%.*]], ptr [[P:%.*]]) {160; CHECK-NEXT:  entry:161; CHECK-NEXT:    [[V1:%.*]] = load i32, ptr [[P]], align 4, !invariant.load [[META0]]162; CHECK-NEXT:    br i1 [[CND]], label [[TAKEN:%.*]], label [[MERGE:%.*]]163; CHECK:       taken:164; CHECK-NEXT:    [[P2:%.*]] = call ptr (...) @bar(ptr [[P]])165; CHECK-NEXT:    [[V2_PRE:%.*]] = load i32, ptr [[P2]], align 4, !invariant.load [[META0]]166; CHECK-NEXT:    br label [[MERGE]]167; CHECK:       merge:168; CHECK-NEXT:    [[V2:%.*]] = phi i32 [ [[V1]], [[ENTRY:%.*]] ], [ [[V2_PRE]], [[TAKEN]] ]169; CHECK-NEXT:    [[P3:%.*]] = phi ptr [ [[P]], [[ENTRY]] ], [ [[P2]], [[TAKEN]] ]170; CHECK-NEXT:    [[RES:%.*]] = sub i32 [[V1]], [[V2]]171; CHECK-NEXT:    ret i32 [[RES]]172;173entry:174  %v1 = load i32, ptr %p, !invariant.load !0175  br i1 %cnd, label %taken, label %merge176taken:177  %p2 = call ptr (...) @bar(ptr %p)178  br label %merge179merge:180  %p3 = phi ptr [%p, %entry], [%p2, %taken]181  %v2 = load i32, ptr %p3, !invariant.load !0182  %res = sub i32 %v1, %v2183  ret i32 %res184}185 186define i32 @metadata_preservation(ptr nocapture %p, ptr nocapture %q) {187; CHECK-LABEL: define i32 @metadata_preservation188; CHECK-SAME: (ptr captures(none) [[P:%.*]], ptr captures(none) [[Q:%.*]]) {189; CHECK-NEXT:  entry:190; CHECK-NEXT:    [[X:%.*]] = load i32, ptr [[P]], align 4, !invariant.load [[META0]]191; CHECK-NEXT:    [[ADD:%.*]] = add i32 [[X]], [[X]]192; CHECK-NEXT:    ret i32 [[ADD]]193;194entry:195  %x = load i32, ptr %p, align 4, !invariant.load !0196  %y = load i32, ptr %p, align 4197  %add = add i32 %x, %y198  ret i32 %add199}200 201!0 = !{ }202 203