diff --git a/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll b/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll --- a/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll +++ b/llvm/test/Transforms/InstCombine/consecutive-ptrmask.ll @@ -65,3 +65,42 @@ %p1 = call ptr @llvm.ptrmask.p0.i32(ptr %p0, i32 %m1) ret ptr %p1 } + + +define ptr @fold_2x_type_mismatch_const0(ptr %p, i32 %m1) { +; CHECK-LABEL: define ptr @fold_2x_type_mismatch_const0 +; CHECK-SAME: (ptr [[P:%.*]], i32 [[M1:%.*]]) { +; CHECK-NEXT: [[P0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -128) +; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 [[M1]]) +; CHECK-NEXT: ret ptr [[P1]] +; + %p0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -128) + %p1 = call ptr @llvm.ptrmask.p0.i32(ptr %p0, i32 %m1) + ret ptr %p1 +} + +define ptr @fold_2x_type_mismatch_const1(ptr %p, i64 %m0) { +; CHECK-LABEL: define ptr @fold_2x_type_mismatch_const1 +; CHECK-SAME: (ptr [[P:%.*]], i64 [[M0:%.*]]) { +; CHECK-NEXT: [[P0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 [[M0]]) +; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 -2) +; CHECK-NEXT: ret ptr [[P1]] +; + %p0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m0) + %p1 = call ptr @llvm.ptrmask.p0.i32(ptr %p0, i32 -2) + ret ptr %p1 +} + + +define ptr @fold_2x_type_mismatch_const2(ptr %p) { +; CHECK-LABEL: define ptr @fold_2x_type_mismatch_const2 +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: [[P0:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -4) +; CHECK-NEXT: [[P1:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 -31) +; CHECK-NEXT: ret ptr [[P1]] +; + %p0 = call ptr @llvm.ptrmask.p0.i32(ptr %p, i32 -4) + %p1 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 -31) + ret ptr %p1 +} + diff --git a/llvm/test/Transforms/InstCombine/ptrmask.ll b/llvm/test/Transforms/InstCombine/ptrmask.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/ptrmask.ll @@ -0,0 +1,154 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt < %s -passes=instcombine -S | FileCheck %s + +declare ptr @llvm.ptrmask.p0.i32(ptr, i32) +declare ptr @llvm.ptrmask.p0.i64(ptr, i64) + +define ptr @ptrmask_combine_consecutive_preserve_attrs(ptr %p0, i64 %m1) { +; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs +; CHECK-SAME: (ptr [[P0:%.*]], i64 [[M1:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[M1]], 224 +; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[TMP1]]) +; CHECK-NEXT: ret ptr [[R]] +; + %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224) + %r = call noalias ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 %m1) + ret ptr %r +} + +define ptr @ptrmask_combine_consecutive_preserve_attrs_fail(ptr %p0, i64 %m0) { +; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_fail +; CHECK-SAME: (ptr [[P0:%.*]], i64 [[M0:%.*]]) { +; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[M0]], 193 +; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 [[TMP1]]) +; CHECK-NEXT: ret ptr [[R]] +; + %pm0 = call noalias ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 %m0) + %r = call ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 193) + ret ptr %r +} + +define ptr @ptrmask_combine_consecutive_preserve_attrs_todo0(ptr %p0) { +; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo0 +; CHECK-SAME: (ptr [[P0:%.*]]) { +; CHECK-NEXT: [[PM0:%.*]] = call noalias ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224) +; CHECK-NEXT: ret ptr [[PM0]] +; + %pm0 = call noalias ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224) + %r = call ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 224) + ret ptr %r +} + +define ptr @ptrmask_combine_consecutive_preserve_attrs_todo1(ptr %p0) { +; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo1 +; CHECK-SAME: (ptr [[P0:%.*]]) { +; CHECK-NEXT: [[PM0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P0]], i64 224) +; CHECK-NEXT: ret ptr [[PM0]] +; + %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p0, i64 224) + %r = call noalias ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 224) + ret ptr %r +} + +define ptr @ptrmask_combine_consecutive_preserve_attrs_todo2(ptr %p0) { +; CHECK-LABEL: define ptr @ptrmask_combine_consecutive_preserve_attrs_todo2 +; CHECK-SAME: (ptr [[P0:%.*]]) { +; CHECK-NEXT: [[PM0:%.*]] = call noalias ptr @llvm.ptrmask.p0.i32(ptr [[P0]], i32 224) +; CHECK-NEXT: ret ptr [[PM0]] +; + %pm0 = call noalias ptr @llvm.ptrmask.p0.i32(ptr %p0, i32 224) + %r = call ptr @llvm.ptrmask.p0.i64(ptr %pm0, i64 224) + ret ptr %r +} + +define ptr @ptrmask_combine_add_nonnull(ptr %p) { +; CHECK-LABEL: define ptr @ptrmask_combine_add_nonnull +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: [[PM0:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -64) +; CHECK-NEXT: [[PGEP:%.*]] = getelementptr i8, ptr [[PM0]], i64 33 +; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[PGEP]], i64 -16) +; CHECK-NEXT: ret ptr [[R]] +; + %pm0 = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -64) + %pgep = getelementptr i8, ptr %pm0, i64 33 + %r = call ptr @llvm.ptrmask.p0.i64(ptr %pgep, i64 -16) + ret ptr %r +} + +define ptr @ptrmask_combine_add_alignment(ptr %p) { +; CHECK-LABEL: define ptr @ptrmask_combine_add_alignment +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 -64) +; CHECK-NEXT: ret ptr [[R]] +; + %r = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 -64) + ret ptr %r +} + +define ptr @ptrmask_combine_add_alignment2(ptr align 32 %p) { +; CHECK-LABEL: define ptr @ptrmask_combine_add_alignment2 +; CHECK-SAME: (ptr align 32 [[P:%.*]]) { +; CHECK-NEXT: [[R:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -64) +; CHECK-NEXT: ret ptr [[R]] +; + %r = call ptr @llvm.ptrmask.p0.i32(ptr %p, i32 -64) + ret ptr %r +} + +define ptr @ptrmask_combine_improve_alignment(ptr %p) { +; CHECK-LABEL: define ptr @ptrmask_combine_improve_alignment +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: [[R:%.*]] = call align 32 ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -64) +; CHECK-NEXT: ret ptr [[R]] +; + %r = call align 32 ptr @llvm.ptrmask.p0.i32(ptr %p, i32 -64) + ret ptr %r +} + +define ptr @ptrmask_combine_improve_alignment_fail(ptr %p) { +; CHECK-LABEL: define ptr @ptrmask_combine_improve_alignment_fail +; CHECK-SAME: (ptr [[P:%.*]]) { +; CHECK-NEXT: [[R:%.*]] = call align 128 ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 -64) +; CHECK-NEXT: ret ptr [[R]] +; + %r = call align 128 ptr @llvm.ptrmask.p0.i32(ptr %p, i32 -64) + ret ptr %r +} + +define i64 @ptrtoint_of_ptrmask(ptr %p, i64 %m) { +; CHECK-LABEL: define i64 @ptrtoint_of_ptrmask +; CHECK-SAME: (ptr [[P:%.*]], i64 [[M:%.*]]) { +; CHECK-NEXT: [[PM:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 [[M]]) +; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[PM]] to i64 +; CHECK-NEXT: ret i64 [[R]] +; + %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m) + %r = ptrtoint ptr %pm to i64 + ret i64 %r +} + +; This succeeds because (ptrtoint i32) gets folded to (trunc i32 (ptrtoint i64)) +define i32 @ptrtoint_of_ptrmask2(ptr %p, i64 %m) { +; CHECK-LABEL: define i32 @ptrtoint_of_ptrmask2 +; CHECK-SAME: (ptr [[P:%.*]], i64 [[M:%.*]]) { +; CHECK-NEXT: [[PM:%.*]] = call ptr @llvm.ptrmask.p0.i64(ptr [[P]], i64 [[M]]) +; CHECK-NEXT: [[TMP1:%.*]] = ptrtoint ptr [[PM]] to i64 +; CHECK-NEXT: [[R:%.*]] = trunc i64 [[TMP1]] to i32 +; CHECK-NEXT: ret i32 [[R]] +; + %pm = call ptr @llvm.ptrmask.p0.i64(ptr %p, i64 %m) + %r = ptrtoint ptr %pm to i32 + ret i32 %r +} + +define i64 @ptrtoint_of_ptrmask_fail(ptr %p, i32 %m) { +; CHECK-LABEL: define i64 @ptrtoint_of_ptrmask_fail +; CHECK-SAME: (ptr [[P:%.*]], i32 [[M:%.*]]) { +; CHECK-NEXT: [[PM:%.*]] = call ptr @llvm.ptrmask.p0.i32(ptr [[P]], i32 [[M]]) +; CHECK-NEXT: [[R:%.*]] = ptrtoint ptr [[PM]] to i64 +; CHECK-NEXT: ret i64 [[R]] +; + %pm = call ptr @llvm.ptrmask.p0.i32(ptr %p, i32 %m) + %r = ptrtoint ptr %pm to i64 + ret i64 %r +}