diff --git a/llvm/test/Transforms/InstCombine/cheri-memcpy-64bit-cap.ll b/llvm/test/Transforms/InstCombine/cheri-memcpy-64bit-cap.ll new file mode 100644 index 000000000000..da3ad71c5c60 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/cheri-memcpy-64bit-cap.ll @@ -0,0 +1,77 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -instcombine -S | FileCheck %s +target datalayout = "e-m:e-pf200:64:64:64:32-p:32:32-i64:64-n32-S128-A200-P200-G200" + +;; memcpy has capability size and alignment, and may copy a capability + +define ptr addrspace(200) @test_memcpy_cap(ptr addrspace(200) %d, ptr addrspace(200) %s) { +; CHECK-LABEL: @test_memcpy_cap( +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(200) [[S:%.*]], align 8 +; CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(200) [[D:%.*]], align 8 +; CHECK-NEXT: ret ptr addrspace(200) [[D]] +; + call void @llvm.memcpy.p200.p200.i32(ptr addrspace(200) align 8 %d, ptr addrspace(200) align 8 %s, i32 8, i1 false) must_preserve_cheri_tags + ret ptr addrspace(200) %d +} + +;; memcpy may contain a capability, but alignment is not known + +define ptr addrspace(200) @test_memcpy8_align_unknown(ptr addrspace(200) %d, ptr addrspace(200) %s) { +; CHECK-LABEL: @test_memcpy8_align_unknown( +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(200) [[S:%.*]], align 1 +; CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(200) [[D:%.*]], align 1 +; CHECK-NEXT: ret ptr addrspace(200) [[D]] +; + call void @llvm.memcpy.p200.p200.i32(ptr addrspace(200) %d, ptr addrspace(200) %s, i32 8, i1 false) must_preserve_cheri_tags + ret ptr addrspace(200) %d +} + +;; memcpy may contain a capability, but alignment may not be sufficient for capability load/store + +define ptr addrspace(200) @test_memcpy8_align_4(ptr addrspace(200) %d, ptr addrspace(200) %s) { +; CHECK-LABEL: @test_memcpy8_align_4( +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(200) [[S:%.*]], align 4 +; CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(200) [[D:%.*]], align 4 +; CHECK-NEXT: ret ptr addrspace(200) [[D]] +; + call void @llvm.memcpy.p200.p200.i32(ptr addrspace(200) align 4 %d, ptr addrspace(200) align 4 %s, i32 8, i1 false) must_preserve_cheri_tags + ret ptr addrspace(200) %d +} + +;; memcpy does not copy capabilities, so can be transformed to regular load/store + +define ptr addrspace(200) @test_memcpy8_nocap(ptr addrspace(200) %d, ptr addrspace(200) %s) { +; CHECK-LABEL: @test_memcpy8_nocap( +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(200) [[S:%.*]], align 8 +; CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(200) [[D:%.*]], align 8 +; CHECK-NEXT: ret ptr addrspace(200) [[D]] +; + call void @llvm.memcpy.p200.p200.i32(ptr addrspace(200) align 8 %d, ptr addrspace(200) align 8 %s, i32 8, i1 false) no_preserve_cheri_tags + ret ptr addrspace(200) %d +} + +;; memcpy has unknown alignment but does not copy capabilities, so can be transformed to regular load/store + +define ptr addrspace(200) @test_memcpy8_nocap_align_unknown(ptr addrspace(200) %d, ptr addrspace(200) %s) { +; CHECK-LABEL: @test_memcpy8_nocap_align_unknown( +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(200) [[S:%.*]], align 1 +; CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(200) [[D:%.*]], align 1 +; CHECK-NEXT: ret ptr addrspace(200) [[D]] +; + call void @llvm.memcpy.p200.p200.i32(ptr addrspace(200) %d, ptr addrspace(200) %s, i32 8, i1 false) no_preserve_cheri_tags + ret ptr addrspace(200) %d +} + +;; memcpy has align 4 and does not copy capabilities, so can be transformed to regular load/store + +define ptr addrspace(200) @test_memcpy8_nocap_align_4(ptr addrspace(200) %d, ptr addrspace(200) %s) { +; CHECK-LABEL: @test_memcpy8_nocap_align_4( +; CHECK-NEXT: [[TMP1:%.*]] = load i64, ptr addrspace(200) [[S:%.*]], align 4 +; CHECK-NEXT: store i64 [[TMP1]], ptr addrspace(200) [[D:%.*]], align 4 +; CHECK-NEXT: ret ptr addrspace(200) [[D]] +; + call void @llvm.memcpy.p200.p200.i32(ptr addrspace(200) align 4 %d, ptr addrspace(200) align 4 %s, i32 8, i1 false) no_preserve_cheri_tags + ret ptr addrspace(200) %d +} + +declare void @llvm.memcpy.p200.p200.i32(ptr addrspace(200), ptr addrspace(200), i32, i1 immarg)