brintos

brintos / llvm-project-archived public Read only

0
0
Text · 16.1 KiB · a389801 Raw
475 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 52; RUN: opt < %s -passes=gvn -S | FileCheck %s3 4target datalayout = "p1:64:64:64:32"5 6%struct.A = type { ptr }7@_ZTV1A = available_externally unnamed_addr constant [4 x ptr] [ptr null, ptr @_ZTI1A, ptr @_ZN1A3fooEv, ptr @_ZN1A3barEv], align 88@_ZTI1A = external constant ptr9 10; Checks if indirect calls can be replaced with direct11; assuming that %vtable == @_ZTV1A (with alignment).12; Checking const propagation across other BBs13 14define void @_Z1gb(i1 zeroext %p) {15; CHECK-LABEL: define void @_Z1gb(16; CHECK-SAME: i1 zeroext [[P:%.*]]) {17; CHECK-NEXT:  [[ENTRY:.*:]]18; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias ptr @_Znwm(i64 8)19; CHECK-NEXT:    tail call void @_ZN1AC1Ev(ptr [[CALL]])20; CHECK-NEXT:    [[VTABLE:%.*]] = load ptr, ptr [[CALL]], align 821; CHECK-NEXT:    [[CMP_VTABLES:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)22; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP_VTABLES]])23; CHECK-NEXT:    br i1 [[P]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]24; CHECK:       [[IF_THEN]]:25; CHECK-NEXT:    [[CALL2:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])26; CHECK-NEXT:    br label %[[IF_END:.*]]27; CHECK:       [[IF_ELSE]]:28; CHECK-NEXT:    [[CALL5:%.*]] = tail call i32 @_ZN1A3barEv(ptr [[CALL]])29; CHECK-NEXT:    br label %[[IF_END]]30; CHECK:       [[IF_END]]:31; CHECK-NEXT:    ret void32;33entry:34  %call = tail call noalias ptr @_Znwm(i64 8) #435  tail call void @_ZN1AC1Ev(ptr %call) #136  %vtable = load ptr, ptr %call, align 837  %cmp.vtables = icmp eq ptr %vtable, getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)38  tail call void @llvm.assume(i1 %cmp.vtables)39  br i1 %p, label %if.then, label %if.else40 41if.then:                                          ; preds = %entry42  %0 = load ptr, ptr %vtable, align 843 44  %call2 = tail call i32 %0(ptr %call) #145 46  br label %if.end47 48if.else:                                          ; preds = %entry49  %vfn47 = getelementptr inbounds ptr, ptr %vtable, i64 150 51  %1 = load ptr, ptr %vfn47, align 852 53  %call5 = tail call i32 %1(ptr %call) #154  br label %if.end55 56if.end:                                           ; preds = %if.else, %if.then57  ret void58}59 60; Check integration with invariant.group handling61define void @invariantGroupHandling(i1 zeroext %p) {62; CHECK-LABEL: define void @invariantGroupHandling(63; CHECK-SAME: i1 zeroext [[P:%.*]]) {64; CHECK-NEXT:  [[ENTRY:.*:]]65; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias ptr @_Znwm(i64 8)66; CHECK-NEXT:    tail call void @_ZN1AC1Ev(ptr [[CALL]])67; CHECK-NEXT:    [[VTABLE:%.*]] = load ptr, ptr [[CALL]], align 8, !invariant.group [[META0:![0-9]+]]68; CHECK-NEXT:    [[CMP_VTABLES:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)69; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP_VTABLES]])70; CHECK-NEXT:    br i1 [[P]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]71; CHECK:       [[IF_THEN]]:72; CHECK-NEXT:    [[CALL2:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])73; CHECK-NEXT:    [[CALLX:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])74; CHECK-NEXT:    [[CALLY:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])75; CHECK-NEXT:    [[UNKNOWN:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])76; CHECK-NEXT:    br label %[[IF_END:.*]]77; CHECK:       [[IF_ELSE]]:78; CHECK-NEXT:    [[CALL5:%.*]] = tail call i32 @_ZN1A3barEv(ptr [[CALL]])79; CHECK-NEXT:    br label %[[IF_END]]80; CHECK:       [[IF_END]]:81; CHECK-NEXT:    ret void82;83entry:84  %call = tail call noalias ptr @_Znwm(i64 8) #485  tail call void @_ZN1AC1Ev(ptr %call) #186  %vtable = load ptr, ptr %call, align 8, !invariant.group !087  %cmp.vtables = icmp eq ptr %vtable, getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)88  tail call void @llvm.assume(i1 %cmp.vtables)89  br i1 %p, label %if.then, label %if.else90 91if.then:                                          ; preds = %entry92  %0 = load ptr, ptr %vtable, align 893 94  %call2 = tail call i32 %0(ptr %call) #195  %vtable1 = load ptr, ptr %call, align 8, !invariant.group !096  %call1 = load ptr, ptr %vtable1, align 897  %callx = tail call i32 %call1(ptr %call) #198 99  %vtable2 = load ptr, ptr %call, align 8, !invariant.group !0100  %call4 = load ptr, ptr %vtable2, align 8101  %cally = tail call i32 %call4(ptr %call) #1102 103  %vtable3 = load ptr, ptr %call, align 8, !invariant.group !0104  %vfun = load ptr, ptr %vtable3, align 8105  %unknown = tail call i32 %vfun(ptr %call) #1106 107  br label %if.end108 109if.else:                                          ; preds = %entry110  %vfn47 = getelementptr inbounds ptr, ptr %vtable, i64 1111 112  %1 = load ptr, ptr %vfn47, align 8113 114  %call5 = tail call i32 %1(ptr %call) #1115  br label %if.end116 117if.end:                                           ; preds = %if.else, %if.then118  ret void119}120 121 122; Checking const propagation in the same BB123 124define i32 @main() {125; CHECK-LABEL: define i32 @main() {126; CHECK-NEXT:  [[ENTRY:.*:]]127; CHECK-NEXT:    [[CALL:%.*]] = tail call noalias ptr @_Znwm(i64 8)128; CHECK-NEXT:    tail call void @_ZN1AC1Ev(ptr [[CALL]])129; CHECK-NEXT:    [[VTABLE:%.*]] = load ptr, ptr [[CALL]], align 8130; CHECK-NEXT:    [[CMP_VTABLES:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)131; CHECK-NEXT:    tail call void @llvm.assume(i1 [[CMP_VTABLES]])132; CHECK-NEXT:    [[CALL2:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])133; CHECK-NEXT:    ret i32 0134;135entry:136  %call = tail call noalias ptr @_Znwm(i64 8)137  tail call void @_ZN1AC1Ev(ptr %call)138  %vtable = load ptr, ptr %call, align 8139  %cmp.vtables = icmp eq ptr %vtable, getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)140  tail call void @llvm.assume(i1 %cmp.vtables)141 142  %0 = load ptr, ptr %vtable, align 8143 144  %call2 = tail call i32 %0(ptr %call)145  ret i32 0146}147 148; This tests checks const propatation with fcmp instruction.149 150define float @_Z1gf(float %p) {151; CHECK-LABEL: define float @_Z1gf(152; CHECK-SAME: float [[P:%.*]]) {153; CHECK-NEXT:  [[ENTRY:.*:]]154; CHECK-NEXT:    [[P_ADDR:%.*]] = alloca float, align 4155; CHECK-NEXT:    [[F:%.*]] = alloca float, align 4156; CHECK-NEXT:    store float [[P]], ptr [[P_ADDR]], align 4157; CHECK-NEXT:    store float 3.000000e+00, ptr [[F]], align 4158; CHECK-NEXT:    [[CMP:%.*]] = fcmp oeq float 3.000000e+00, [[P]]159; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])160; CHECK-NEXT:    ret float 3.000000e+00161;162entry:163  %p.addr = alloca float, align 4164  %f = alloca float, align 4165  store float %p, ptr %p.addr, align 4166 167  store float 3.000000e+00, ptr %f, align 4168  %0 = load float, ptr %p.addr, align 4169  %1 = load float, ptr %f, align 4170  %cmp = fcmp oeq float %1, %0 ; note const on lhs171  call void @llvm.assume(i1 %cmp)172 173  ret float %0174}175 176 177define float @_Z1hf(float %p) {178; CHECK-LABEL: define float @_Z1hf(179; CHECK-SAME: float [[P:%.*]]) {180; CHECK-NEXT:  [[ENTRY:.*:]]181; CHECK-NEXT:    [[P_ADDR:%.*]] = alloca float, align 4182; CHECK-NEXT:    store float [[P]], ptr [[P_ADDR]], align 4183; CHECK-NEXT:    [[CMP:%.*]] = fcmp nnan ueq float [[P]], 3.000000e+00184; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])185; CHECK-NEXT:    ret float 3.000000e+00186;187entry:188  %p.addr = alloca float, align 4189  store float %p, ptr %p.addr, align 4190 191  %0 = load float, ptr %p.addr, align 4192  %cmp = fcmp nnan ueq float %0, 3.000000e+00193  call void @llvm.assume(i1 %cmp)194 195  ret float %0196}197 198define float @_Z1if(float %p) {199; CHECK-LABEL: define float @_Z1if(200; CHECK-SAME: float [[P:%.*]]) {201; CHECK-NEXT:  [[ENTRY:.*:]]202; CHECK-NEXT:    [[P_ADDR:%.*]] = alloca float, align 4203; CHECK-NEXT:    store float [[P]], ptr [[P_ADDR]], align 4204; CHECK-NEXT:    [[CMP:%.*]] = fcmp ueq float [[P]], 3.000000e+00205; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])206; CHECK-NEXT:    ret float [[P]]207;208entry:209  %p.addr = alloca float, align 4210  store float %p, ptr %p.addr, align 4211 212  %0 = load float, ptr %p.addr, align 4213  %cmp = fcmp ueq float %0, 3.000000e+00 ; no nnan flag - can't propagate214  call void @llvm.assume(i1 %cmp)215 216  ret float %0217}218 219; This test checks if constant propagation works for multiple node edges220define i32 @_Z1ii(i32 %p) {221; CHECK-LABEL: define i32 @_Z1ii(222; CHECK-SAME: i32 [[P:%.*]]) {223; CHECK-NEXT:  [[ENTRY:.*:]]224; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[P]], 42225; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])226; CHECK-NEXT:    br i1 true, label %[[COMMON:.*]], label %[[COMMON]]227; CHECK:       [[COMMON]]:228; CHECK-NEXT:    br i1 true, label %[[COMMON]], label %[[COMMON]]229; CHECK:       [[EXIT:.*:]]230; CHECK-NEXT:    ret i32 42231;232entry:233  %cmp = icmp eq i32 %p, 42234  call void @llvm.assume(i1 %cmp)235 236  br i1 %cmp, label %common, label %common237common:238  call void @llvm.assume(i1 true)239  br i1 %cmp, label %common, label %common240 241exit:242  ret i32 %p243}244 245define i32 @_Z1ij(i32 %p) {246; CHECK-LABEL: define i32 @_Z1ij(247; CHECK-SAME: i32 [[P:%.*]]) {248; CHECK-NEXT:  [[ENTRY:.*:]]249; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[P]], 42250; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])251; CHECK-NEXT:    br i1 true, label %[[BB2:.*]], label %[[BB2]]252; CHECK:       [[BB2]]:253; CHECK-NEXT:    br i1 true, label %[[BB2]], label %[[BB2]]254; CHECK:       [[BB0:.*:]]255; CHECK-NEXT:    ret i32 42256;257entry:258  %cmp = icmp eq i32 %p, 42259  call void @llvm.assume(i1 %cmp)260 261  br i1 %cmp, label %bb2, label %bb2262bb2:263  %cmp2 = icmp eq i32 %p, 42264  call void @llvm.assume(i1 %cmp2)265 266  br i1 %cmp, label %bb2, label %bb2267 268  ret i32 %p269}270 271define i32 @_Z1ik(i32 %p) {272; CHECK-LABEL: define i32 @_Z1ik(273; CHECK-SAME: i32 [[P:%.*]]) {274; CHECK-NEXT:  [[ENTRY:.*:]]275; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[P]], 42276; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])277; CHECK-NEXT:    br i1 true, label %[[BB2:.*]], label %[[BB3:.*]]278; CHECK:       [[BB2]]:279; CHECK-NEXT:    store i8 poison, ptr null, align 1280; CHECK-NEXT:    ret i32 15281; CHECK:       [[BB3]]:282; CHECK-NEXT:    ret i32 17283;284entry:285  %cmp = icmp eq i32 %p, 42286  call void @llvm.assume(i1 %cmp)287 288  br i1 %cmp, label %bb2, label %bb3289bb2:290  %cmp3 = icmp eq i32 %p, 43291  call void @llvm.assume(i1 %cmp3)292  ret i32 15293bb3:294  ret i32 17295}296 297; This test checks if GVN can do the constant propagation correctly298; when there are multiple uses of the same assume value in the299; basic block that has a loop back-edge pointing to itself.300;301define i32 @_Z1il(i32 %val, i1 %k) {302; CHECK-LABEL: define i32 @_Z1il(303; CHECK-SAME: i32 [[VAL:%.*]], i1 [[K:%.*]]) {304; CHECK-NEXT:    br label %[[NEXT:.*]]305; CHECK:       [[NEXT]]:306; CHECK-NEXT:    tail call void @llvm.assume(i1 [[K]])307; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[VAL]], 50308; CHECK-NEXT:    br i1 [[CMP]], label %[[NEXT]], label %[[MEH:.*]]309; CHECK:       [[MEH]]:310; CHECK-NEXT:    ret i32 0311;312  br label %next313 314next:315  tail call void @llvm.assume(i1 %k)316  tail call void @llvm.assume(i1 %k)317  %cmp = icmp eq i32 %val, 50318  br i1 %cmp, label %next, label %meh319 320meh:321  ret i32 0322}323 324; This test checks if GVN can prevent the constant propagation correctly325; in the successor blocks that are not dominated by the basic block326; with the assume instruction.327;328define i1 @_z1im(i32 %val, i1 %k, i1 %j) {329; CHECK-LABEL: define i1 @_z1im(330; CHECK-SAME: i32 [[VAL:%.*]], i1 [[K:%.*]], i1 [[J:%.*]]) {331; CHECK-NEXT:    br i1 [[J]], label %[[NEXT:.*]], label %[[MEH:.*]]332; CHECK:       [[NEXT]]:333; CHECK-NEXT:    tail call void @llvm.assume(i1 [[K]])334; CHECK-NEXT:    br label %[[MEH]]335; CHECK:       [[MEH]]:336; CHECK-NEXT:    ret i1 [[K]]337;338  br i1 %j, label %next, label %meh339 340next:341  tail call void @llvm.assume(i1 %k)342  tail call void @llvm.assume(i1 %k)343  br label %meh344 345meh:346  ret i1 %k347}348 349define i8 @assume_ptr_eq_different_prov_matters(ptr %p, ptr %p2) {350; CHECK-LABEL: define i8 @assume_ptr_eq_different_prov_matters(351; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]]) {352; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P]], [[P2]]353; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])354; CHECK-NEXT:    [[V:%.*]] = load i8, ptr [[P2]], align 1355; CHECK-NEXT:    ret i8 [[V]]356;357  %cmp = icmp eq ptr %p, %p2358  call void @llvm.assume(i1 %cmp)359  %v = load i8, ptr %p2360  ret i8 %v361}362 363define i1 @assume_ptr_eq_different_prov_does_not_matter_icmp(ptr %p, ptr %p2) {364; CHECK-LABEL: define i1 @assume_ptr_eq_different_prov_does_not_matter_icmp(365; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]]) {366; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P]], [[P2]]367; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])368; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr [[P]], null369; CHECK-NEXT:    ret i1 [[C]]370;371  %cmp = icmp eq ptr %p, %p2372  call void @llvm.assume(i1 %cmp)373  %c = icmp eq ptr %p2, null374  ret i1 %c375}376 377define i1 @assume_ptr_eq_different_prov_does_not_matter_icmp_addrsize(ptr addrspace(1) %p, ptr addrspace(1) %p2) {378; CHECK-LABEL: define i1 @assume_ptr_eq_different_prov_does_not_matter_icmp_addrsize(379; CHECK-SAME: ptr addrspace(1) [[P:%.*]], ptr addrspace(1) [[P2:%.*]]) {380; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr addrspace(1) [[P]], [[P2]]381; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])382; CHECK-NEXT:    [[C:%.*]] = icmp eq ptr addrspace(1) [[P]], null383; CHECK-NEXT:    ret i1 [[C]]384;385  %cmp = icmp eq ptr addrspace(1) %p, %p2386  call void @llvm.assume(i1 %cmp)387  %c = icmp eq ptr addrspace(1) %p2, null388  ret i1 %c389}390 391; This is not correct, as it may change the provenance exposed by ptrtoint.392; We still allow it for now.393define i64 @assume_ptr_eq_different_prov_does_not_matter_ptrtoint(ptr %p, ptr %p2) {394; CHECK-LABEL: define i64 @assume_ptr_eq_different_prov_does_not_matter_ptrtoint(395; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]]) {396; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P]], [[P2]]397; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])398; CHECK-NEXT:    [[INT:%.*]] = ptrtoint ptr [[P]] to i64399; CHECK-NEXT:    ret i64 [[INT]]400;401  %cmp = icmp eq ptr %p, %p2402  call void @llvm.assume(i1 %cmp)403  %int = ptrtoint ptr %p2 to i64404  ret i64 %int405}406 407define i64 @assume_ptr_eq_different_prov_does_not_matter_ptrtoint_addrsize(ptr addrspace(1) %p, ptr addrspace(1) %p2) {408; CHECK-LABEL: define i64 @assume_ptr_eq_different_prov_does_not_matter_ptrtoint_addrsize(409; CHECK-SAME: ptr addrspace(1) [[P:%.*]], ptr addrspace(1) [[P2:%.*]]) {410; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr addrspace(1) [[P]], [[P2]]411; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])412; CHECK-NEXT:    [[INT:%.*]] = ptrtoint ptr addrspace(1) [[P]] to i64413; CHECK-NEXT:    ret i64 [[INT]]414;415  %cmp = icmp eq ptr addrspace(1) %p, %p2416  call void @llvm.assume(i1 %cmp)417  %int = ptrtoint ptr addrspace(1) %p2 to i64418  ret i64 %int419}420 421define i64 @assume_ptr_eq_different_prov_does_not_matter_ptrtoaddr(ptr %p, ptr %p2) {422; CHECK-LABEL: define i64 @assume_ptr_eq_different_prov_does_not_matter_ptrtoaddr(423; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]]) {424; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P]], [[P2]]425; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])426; CHECK-NEXT:    [[INT:%.*]] = ptrtoaddr ptr [[P]] to i64427; CHECK-NEXT:    ret i64 [[INT]]428;429  %cmp = icmp eq ptr %p, %p2430  call void @llvm.assume(i1 %cmp)431  %int = ptrtoaddr ptr %p2 to i64432  ret i64 %int433}434 435define i32 @assume_ptr_eq_different_prov_does_not_matter_ptrtoaddr_addrsize(ptr addrspace(1) %p, ptr addrspace(1) %p2) {436; CHECK-LABEL: define i32 @assume_ptr_eq_different_prov_does_not_matter_ptrtoaddr_addrsize(437; CHECK-SAME: ptr addrspace(1) [[P:%.*]], ptr addrspace(1) [[P2:%.*]]) {438; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr addrspace(1) [[P]], [[P2]]439; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])440; CHECK-NEXT:    [[INT:%.*]] = ptrtoaddr ptr addrspace(1) [[P]] to i32441; CHECK-NEXT:    ret i32 [[INT]]442;443  %cmp = icmp eq ptr addrspace(1) %p, %p2444  call void @llvm.assume(i1 %cmp)445  %int = ptrtoaddr ptr addrspace(1) %p2 to i32446  ret i32 %int447}448 449define i8 @assume_ptr_eq_same_prov(ptr %p, i64 %x) {450; CHECK-LABEL: define i8 @assume_ptr_eq_same_prov(451; CHECK-SAME: ptr [[P:%.*]], i64 [[X:%.*]]) {452; CHECK-NEXT:    [[P2:%.*]] = getelementptr i8, ptr [[P]], i64 [[X]]453; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P]], [[P2]]454; CHECK-NEXT:    call void @llvm.assume(i1 [[CMP]])455; CHECK-NEXT:    [[V:%.*]] = load i8, ptr [[P]], align 1456; CHECK-NEXT:    ret i8 [[V]]457;458  %p2 = getelementptr i8, ptr %p, i64 %x459  %cmp = icmp eq ptr %p, %p2460  call void @llvm.assume(i1 %cmp)461  %v = load i8, ptr %p2462  ret i8 %v463}464 465declare noalias ptr @_Znwm(i64)466declare void @_ZN1AC1Ev(ptr)467declare void @llvm.assume(i1)468declare i32 @_ZN1A3fooEv(ptr)469declare i32 @_ZN1A3barEv(ptr)470 471!0 = !{!"struct A"}472;.473; CHECK: [[META0]] = !{!"struct A"}474;.475