brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.0 KiB · adf3aa1 Raw
312 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 62; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4; The ptrtoaddr folds are also valid for pointers that have external state.5target datalayout = "pe1:64:64:64:32"6 7declare void @use.i1(i1)8declare void @use.i32(i32)9declare void @use.i64(i64)10 11; ptrtoaddr result type is fixed, and can't be combined with integer cast.12define i32 @ptrtoaddr_trunc(ptr %p) {13; CHECK-LABEL: define i32 @ptrtoaddr_trunc(14; CHECK-SAME: ptr [[P:%.*]]) {15; CHECK-NEXT:    [[P_ADDR:%.*]] = ptrtoaddr ptr [[P]] to i6416; CHECK-NEXT:    [[TRUNC:%.*]] = trunc i64 [[P_ADDR]] to i3217; CHECK-NEXT:    ret i32 [[TRUNC]]18;19  %p.addr = ptrtoaddr ptr %p to i6420  %trunc = trunc i64 %p.addr to i3221  ret i32 %trunc22}23 24define i128 @ptrtoaddr_zext(ptr %p) {25; CHECK-LABEL: define i128 @ptrtoaddr_zext(26; CHECK-SAME: ptr [[P:%.*]]) {27; CHECK-NEXT:    [[P_ADDR:%.*]] = ptrtoaddr ptr [[P]] to i6428; CHECK-NEXT:    [[EXT:%.*]] = zext i64 [[P_ADDR]] to i12829; CHECK-NEXT:    ret i128 [[EXT]]30;31  %p.addr = ptrtoaddr ptr %p to i6432  %ext = zext i64 %p.addr to i12833  ret i128 %ext34}35 36define i128 @ptrtoaddr_sext(ptr %p) {37; CHECK-LABEL: define i128 @ptrtoaddr_sext(38; CHECK-SAME: ptr [[P:%.*]]) {39; CHECK-NEXT:    [[P_ADDR:%.*]] = ptrtoaddr ptr [[P]] to i6440; CHECK-NEXT:    [[EXT:%.*]] = sext i64 [[P_ADDR]] to i12841; CHECK-NEXT:    ret i128 [[EXT]]42;43  %p.addr = ptrtoaddr ptr %p to i6444  %ext = sext i64 %p.addr to i12845  ret i128 %ext46}47 48define i64 @sub_ptrtoaddr(ptr %p, i64 %offset) {49; CHECK-LABEL: define i64 @sub_ptrtoaddr(50; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFSET:%.*]]) {51; CHECK-NEXT:    ret i64 [[OFFSET]]52;53  %p2 = getelementptr i8, ptr %p, i64 %offset54  %p.addr = ptrtoaddr ptr %p to i6455  %p2.addr = ptrtoaddr ptr %p2 to i6456  %sub = sub i64 %p2.addr, %p.addr57  ret i64 %sub58}59 60define i64 @sub_ptrtoint_ptrtoaddr(ptr %p, i64 %offset) {61; CHECK-LABEL: define i64 @sub_ptrtoint_ptrtoaddr(62; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFSET:%.*]]) {63; CHECK-NEXT:    ret i64 [[OFFSET]]64;65  %p2 = getelementptr i8, ptr %p, i64 %offset66  %p.int = ptrtoint ptr %p to i6467  %p2.addr = ptrtoaddr ptr %p2 to i6468  %sub = sub i64 %p2.addr, %p.int69  ret i64 %sub70}71 72define i32 @sub_ptrtoaddr_addrsize(ptr addrspace(1) %p, i32 %offset) {73; CHECK-LABEL: define i32 @sub_ptrtoaddr_addrsize(74; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {75; CHECK-NEXT:    ret i32 [[OFFSET]]76;77  %p2 = getelementptr i8, ptr addrspace(1) %p, i32 %offset78  %p.addr = ptrtoaddr ptr addrspace(1) %p to i3279  %p2.addr = ptrtoaddr ptr addrspace(1) %p2 to i3280  %sub = sub i32 %p2.addr, %p.addr81  ret i32 %sub82}83 84define i32 @sub_trunc_ptrtoaddr(ptr %p, i64 %offset) {85; CHECK-LABEL: define i32 @sub_trunc_ptrtoaddr(86; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFSET:%.*]]) {87; CHECK-NEXT:    [[SUB:%.*]] = trunc i64 [[OFFSET]] to i3288; CHECK-NEXT:    ret i32 [[SUB]]89;90  %p2 = getelementptr i8, ptr %p, i64 %offset91  %p.addr = ptrtoaddr ptr %p to i6492  %p2.addr = ptrtoaddr ptr %p2 to i6493  %p.addr.trunc = trunc i64 %p.addr to i3294  %p2.addr.trunc = trunc i64 %p2.addr to i3295  %sub = sub i32 %p2.addr.trunc, %p.addr.trunc96  ret i32 %sub97}98 99define i16 @sub_trunc_ptrtoaddr_addrsize(ptr addrspace(1) %p, i32 %offset) {100; CHECK-LABEL: define i16 @sub_trunc_ptrtoaddr_addrsize(101; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {102; CHECK-NEXT:    [[SUB:%.*]] = trunc i32 [[OFFSET]] to i16103; CHECK-NEXT:    ret i16 [[SUB]]104;105  %p2 = getelementptr i8, ptr addrspace(1) %p, i32 %offset106  %p.addr = ptrtoaddr ptr addrspace(1) %p to i32107  %p2.addr = ptrtoaddr ptr addrspace(1) %p2 to i32108  %p.addr.trunc = trunc i32 %p.addr to i16109  %p2.addr.trunc = trunc i32 %p2.addr to i16110  %sub = sub i16 %p2.addr.trunc, %p.addr.trunc111  ret i16 %sub112}113 114define i16 @sub_trunc_ptrtoint_ptrtoaddr_addrsize(ptr addrspace(1) %p, i32 %offset) {115; CHECK-LABEL: define i16 @sub_trunc_ptrtoint_ptrtoaddr_addrsize(116; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {117; CHECK-NEXT:    [[SUB:%.*]] = trunc i32 [[OFFSET]] to i16118; CHECK-NEXT:    ret i16 [[SUB]]119;120  %p2 = getelementptr i8, ptr addrspace(1) %p, i32 %offset121  %p.int = ptrtoint ptr addrspace(1) %p to i64122  %p2.addr = ptrtoaddr ptr addrspace(1) %p2 to i32123  %p.int.trunc = trunc i64 %p.int to i16124  %p2.addr.trunc = trunc i32 %p2.addr to i16125  %sub = sub i16 %p2.addr.trunc, %p.int.trunc126  ret i16 %sub127}128 129define i128 @sub_zext_ptrtoaddr(ptr %p, i64 %offset) {130; CHECK-LABEL: define i128 @sub_zext_ptrtoaddr(131; CHECK-SAME: ptr [[P:%.*]], i64 [[OFFSET:%.*]]) {132; CHECK-NEXT:    [[SUB:%.*]] = zext i64 [[OFFSET]] to i128133; CHECK-NEXT:    ret i128 [[SUB]]134;135  %p2 = getelementptr nuw i8, ptr %p, i64 %offset136  %p.addr = ptrtoaddr ptr %p to i64137  %p2.addr = ptrtoaddr ptr %p2 to i64138  %p.addr.ext = zext i64 %p.addr to i128139  %p2.addr.ext = zext i64 %p2.addr to i128140  %sub = sub i128 %p2.addr.ext, %p.addr.ext141  ret i128 %sub142}143 144define i64 @sub_zext_ptrtoaddr_addrsize(ptr addrspace(1) %p, i32 %offset) {145; CHECK-LABEL: define i64 @sub_zext_ptrtoaddr_addrsize(146; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {147; CHECK-NEXT:    [[SUB:%.*]] = zext i32 [[OFFSET]] to i64148; CHECK-NEXT:    ret i64 [[SUB]]149;150  %p2 = getelementptr nuw i8, ptr addrspace(1) %p, i32 %offset151  %p.addr = ptrtoaddr ptr addrspace(1) %p to i32152  %p2.addr = ptrtoaddr ptr addrspace(1) %p2 to i32153  %p.addr.ext = zext i32 %p.addr to i64154  %p2.addr.ext = zext i32 %p2.addr to i64155  %sub = sub i64 %p2.addr.ext, %p.addr.ext156  ret i64 %sub157}158 159define i128 @sub_zext_ptrtoint_ptrtoaddr_addrsize(ptr addrspace(1) %p, i32 %offset) {160; CHECK-LABEL: define i128 @sub_zext_ptrtoint_ptrtoaddr_addrsize(161; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[OFFSET:%.*]]) {162; CHECK-NEXT:    [[P2:%.*]] = getelementptr nuw i8, ptr addrspace(1) [[P]], i32 [[OFFSET]]163; CHECK-NEXT:    [[P_INT:%.*]] = ptrtoint ptr addrspace(1) [[P]] to i64164; CHECK-NEXT:    [[P2_ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[P2]] to i32165; CHECK-NEXT:    [[P_INT_EXT:%.*]] = zext i64 [[P_INT]] to i128166; CHECK-NEXT:    [[P2_ADDR_EXT:%.*]] = zext i32 [[P2_ADDR]] to i128167; CHECK-NEXT:    [[SUB:%.*]] = sub nsw i128 [[P2_ADDR_EXT]], [[P_INT_EXT]]168; CHECK-NEXT:    ret i128 [[SUB]]169;170  %p2 = getelementptr nuw i8, ptr addrspace(1) %p, i32 %offset171  %p.int = ptrtoint ptr addrspace(1) %p to i64172  %p2.addr = ptrtoaddr ptr addrspace(1) %p2 to i32173  %p.int.ext = zext i64 %p.int to i128174  %p2.addr.ext = zext i32 %p2.addr to i128175  %sub = sub i128 %p2.addr.ext, %p.int.ext176  ret i128 %sub177}178 179; The uses in icmp, ptrtoint, ptrtoaddr should be replaced. The one in the180; return value should not, as the provenance differs.181define ptr @gep_sub_ptrtoaddr_different_obj(ptr %p, ptr %p2, ptr %p3) {182; CHECK-LABEL: define ptr @gep_sub_ptrtoaddr_different_obj(183; CHECK-SAME: ptr [[P:%.*]], ptr [[P2:%.*]], ptr [[P3:%.*]]) {184; CHECK-NEXT:    [[P_ADDR:%.*]] = ptrtoaddr ptr [[P]] to i64185; CHECK-NEXT:    [[P2_ADDR:%.*]] = ptrtoaddr ptr [[P2]] to i64186; CHECK-NEXT:    [[SUB:%.*]] = sub i64 [[P2_ADDR]], [[P_ADDR]]187; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr [[P]], i64 [[SUB]]188; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr [[P2]], [[P3]]189; CHECK-NEXT:    call void @use.i1(i1 [[CMP]])190; CHECK-NEXT:    [[INT:%.*]] = ptrtoint ptr [[P2]] to i64191; CHECK-NEXT:    call void @use.i64(i64 [[INT]])192; CHECK-NEXT:    [[ADDR:%.*]] = ptrtoaddr ptr [[P2]] to i64193; CHECK-NEXT:    call void @use.i64(i64 [[ADDR]])194; CHECK-NEXT:    ret ptr [[GEP]]195;196  %p.addr = ptrtoaddr ptr %p to i64197  %p2.addr = ptrtoaddr ptr %p2 to i64198  %sub = sub i64 %p2.addr, %p.addr199  %gep = getelementptr i8, ptr %p, i64 %sub200  %cmp = icmp eq ptr %gep, %p3201  call void @use.i1(i1 %cmp)202  %int = ptrtoint ptr %gep to i64203  call void @use.i64(i64 %int)204  %addr = ptrtoaddr ptr %gep to i64205  call void @use.i64(i64 %addr)206  ret ptr %gep207}208 209; The use in ptrtoaddr should be replaced. The uses in ptrtoint and icmp should210; not be replaced, as the non-address bits differ. The use in the return value211; should not be replaced as the provenace differs.212define ptr addrspace(1) @gep_sub_ptrtoaddr_different_obj_addrsize(ptr addrspace(1) %p, ptr addrspace(1) %p2, ptr addrspace(1) %p3) {213; CHECK-LABEL: define ptr addrspace(1) @gep_sub_ptrtoaddr_different_obj_addrsize(214; CHECK-SAME: ptr addrspace(1) [[P:%.*]], ptr addrspace(1) [[P2:%.*]], ptr addrspace(1) [[P3:%.*]]) {215; CHECK-NEXT:    [[P_ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[P]] to i32216; CHECK-NEXT:    [[P2_ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[P2]] to i32217; CHECK-NEXT:    [[SUB:%.*]] = sub i32 [[P2_ADDR]], [[P_ADDR]]218; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[P]], i32 [[SUB]]219; CHECK-NEXT:    [[CMP:%.*]] = icmp eq ptr addrspace(1) [[GEP]], [[P3]]220; CHECK-NEXT:    call void @use.i1(i1 [[CMP]])221; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoint ptr addrspace(1) [[GEP]] to i64222; CHECK-NEXT:    [[INT:%.*]] = trunc i64 [[TMP1]] to i32223; CHECK-NEXT:    call void @use.i32(i32 [[INT]])224; CHECK-NEXT:    [[ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[P2]] to i32225; CHECK-NEXT:    call void @use.i32(i32 [[ADDR]])226; CHECK-NEXT:    ret ptr addrspace(1) [[GEP]]227;228  %p.addr = ptrtoaddr ptr addrspace(1) %p to i32229  %p2.addr = ptrtoaddr ptr addrspace(1) %p2 to i32230  %sub = sub i32 %p2.addr, %p.addr231  %gep = getelementptr i8, ptr addrspace(1) %p, i32 %sub232  %cmp = icmp eq ptr addrspace(1) %gep, %p3233  call void @use.i1(i1 %cmp)234  %int = ptrtoint ptr addrspace(1) %gep to i32235  call void @use.i32(i32 %int)236  %addr = ptrtoaddr ptr addrspace(1) %gep to i32237  call void @use.i32(i32 %addr)238  ret ptr addrspace(1) %gep239}240 241define i64 @ptrtoaddr_of_ptrmask(ptr %p, i64 %mask) {242; CHECK-LABEL: define i64 @ptrtoaddr_of_ptrmask(243; CHECK-SAME: ptr [[P:%.*]], i64 [[MASK:%.*]]) {244; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoaddr ptr [[P]] to i64245; CHECK-NEXT:    [[ADDR:%.*]] = and i64 [[MASK]], [[TMP1]]246; CHECK-NEXT:    ret i64 [[ADDR]]247;248  %masked = call ptr @llvm.ptrmask(ptr %p, i64 %mask)249  %addr = ptrtoaddr ptr %masked to i64250  ret i64 %addr251}252 253define i32 @ptrtoaddr_of_ptrmask_addrsize(ptr addrspace(1) %p, i32 %mask) {254; CHECK-LABEL: define i32 @ptrtoaddr_of_ptrmask_addrsize(255; CHECK-SAME: ptr addrspace(1) [[P:%.*]], i32 [[MASK:%.*]]) {256; CHECK-NEXT:    [[TMP1:%.*]] = ptrtoaddr ptr addrspace(1) [[P]] to i32257; CHECK-NEXT:    [[ADDR:%.*]] = and i32 [[MASK]], [[TMP1]]258; CHECK-NEXT:    ret i32 [[ADDR]]259;260  %masked = call ptr addrspace(1) @llvm.ptrmask(ptr addrspace(1) %p, i32 %mask)261  %addr = ptrtoaddr ptr addrspace(1) %masked to i32262  ret i32 %addr263}264 265define i64 @ptrtoaddr_of_gep_of_inttoptr(i64 %int, i64 %offset) {266; CHECK-LABEL: define i64 @ptrtoaddr_of_gep_of_inttoptr(267; CHECK-SAME: i64 [[INT:%.*]], i64 [[OFFSET:%.*]]) {268; CHECK-NEXT:    [[ADDR:%.*]] = add i64 [[INT]], [[OFFSET]]269; CHECK-NEXT:    ret i64 [[ADDR]]270;271  %ptr = inttoptr i64 %int to ptr272  %gep = getelementptr i8, ptr %ptr, i64 %offset273  %addr = ptrtoaddr ptr %gep to i64274  ret i64 %addr275}276 277; FIXME: This could be supported by truncating %int before performing the278; arithmetic.279define i32 @ptrtoaddr_of_gep_of_inttoptr_addrsize(i64 %int, i32 %offset) {280; CHECK-LABEL: define i32 @ptrtoaddr_of_gep_of_inttoptr_addrsize(281; CHECK-SAME: i64 [[INT:%.*]], i32 [[OFFSET:%.*]]) {282; CHECK-NEXT:    [[PTR:%.*]] = inttoptr i64 [[INT]] to ptr addrspace(1)283; CHECK-NEXT:    [[GEP:%.*]] = getelementptr i8, ptr addrspace(1) [[PTR]], i32 [[OFFSET]]284; CHECK-NEXT:    [[ADDR:%.*]] = ptrtoaddr ptr addrspace(1) [[GEP]] to i32285; CHECK-NEXT:    ret i32 [[ADDR]]286;287  %ptr = inttoptr i64 %int to ptr addrspace(1)288  %gep = getelementptr i8, ptr addrspace(1) %ptr, i32 %offset289  %addr = ptrtoaddr ptr addrspace(1) %gep to i32290  ret i32 %addr291}292 293define i64 @ptrtoaddr_of_gep_of_null(i64 %offset) {294; CHECK-LABEL: define i64 @ptrtoaddr_of_gep_of_null(295; CHECK-SAME: i64 [[OFFSET:%.*]]) {296; CHECK-NEXT:    ret i64 [[OFFSET]]297;298  %gep = getelementptr i8, ptr null, i64 %offset299  %addr = ptrtoaddr ptr %gep to i64300  ret i64 %addr301}302 303define i32 @ptrtoaddr_of_gep_of_null_addrsize(i32 %offset) {304; CHECK-LABEL: define i32 @ptrtoaddr_of_gep_of_null_addrsize(305; CHECK-SAME: i32 [[OFFSET:%.*]]) {306; CHECK-NEXT:    ret i32 [[OFFSET]]307;308  %gep = getelementptr i8, ptr addrspace(1) null, i32 %offset309  %addr = ptrtoaddr ptr addrspace(1) %gep to i32310  ret i32 %addr311}312