diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 3b6aa4b6f8356..36fe036aa9e9f 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -6296,12 +6296,6 @@ const SCEV *ScalarEvolution::createNodeForGEP(GEPOperator *GEP) { assert(GEP->getSourceElementType()->isSized() && "GEP source element type must be sized"); - const DataLayout &DL = F.getParent()->getDataLayout(); - // FIXME: Ideally, we should teach Scalar Evolution to - // understand fat pointers. - if (DL.isFatPointer(GEP->getPointerOperandType()->getPointerAddressSpace())) - return getUnknown(GEP); - SmallVector IndexExprs; for (Value *Index : GEP->indices()) IndexExprs.push_back(getSCEV(Index)); diff --git a/llvm/test/CodeGen/RISCV/cheri/calling-conv-il32pc64.ll b/llvm/test/CodeGen/RISCV/cheri/calling-conv-il32pc64.ll index 8f85e4e1c1152..c803b2af2464c 100644 --- a/llvm/test/CodeGen/RISCV/cheri/calling-conv-il32pc64.ll +++ b/llvm/test/CodeGen/RISCV/cheri/calling-conv-il32pc64.ll @@ -13,13 +13,12 @@ define i32 @get_ith_word(i32 signext %i, ...) addrspace(200) nounwind { ; CHECK-NEXT: addi a0, a0, 1 ; CHECK-NEXT: .LBB0_1: # %while.cond ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-NEXT: cmove ca2, ca1 ; CHECK-NEXT: addi a0, a0, -1 ; CHECK-NEXT: cincoffset ca1, ca1, 4 ; CHECK-NEXT: bgtz a0, .LBB0_1 ; CHECK-NEXT: # %bb.2: # %while.end ; CHECK-NEXT: csc ca1, 8(csp) -; CHECK-NEXT: clw a0, 0(ca2) +; CHECK-NEXT: clw a0, -4(ca1) ; CHECK-NEXT: cincoffset csp, csp, 16 ; CHECK-NEXT: cret entry: diff --git a/llvm/test/CodeGen/RISCV/cheri/calling-conv-l64pc128.ll b/llvm/test/CodeGen/RISCV/cheri/calling-conv-l64pc128.ll index 5334d8536fb1d..dc12d89637c4d 100644 --- a/llvm/test/CodeGen/RISCV/cheri/calling-conv-l64pc128.ll +++ b/llvm/test/CodeGen/RISCV/cheri/calling-conv-l64pc128.ll @@ -13,13 +13,12 @@ define i32 @get_ith_word(i32 signext %i, ...) addrspace(200) nounwind { ; CHECK-NEXT: addi a0, a0, 1 ; CHECK-NEXT: .LBB0_1: # %while.cond ; CHECK-NEXT: # =>This Inner Loop Header: Depth=1 -; CHECK-NEXT: cmove ca2, ca1 ; CHECK-NEXT: addiw a0, a0, -1 ; CHECK-NEXT: cincoffset ca1, ca1, 4 ; CHECK-NEXT: bgtz a0, .LBB0_1 ; CHECK-NEXT: # %bb.2: # %while.end ; CHECK-NEXT: csc ca1, 0(csp) -; CHECK-NEXT: clw a0, 0(ca2) +; CHECK-NEXT: clw a0, -4(ca1) ; CHECK-NEXT: cincoffset csp, csp, 16 ; CHECK-NEXT: cret entry: @@ -103,7 +102,6 @@ declare void @varargs(i32, ...) addrspace(200) nounwind ; go in an even integer register pair and would thus reserve the odd register, ; even though we're passing on the stack. define void @test_varargs_odd_cap_reg() addrspace(200) nounwind { -entry: ; CHECK-LABEL: test_varargs_odd_cap_reg: ; CHECK: # %bb.0: # %entry ; CHECK-NEXT: cincoffset csp, csp, -32 @@ -114,6 +112,7 @@ entry: ; CHECK-NEXT: clc cra, 16(csp) # 16-byte Folded Reload ; CHECK-NEXT: cincoffset csp, csp, 32 ; CHECK-NEXT: cret +entry: tail call void (i32, ...) @varargs(i32 1, ptr addrspace(200) null) ret void } diff --git a/llvm/test/Transforms/LoopIdiom/cheri-preserve-tags-memcpy.ll b/llvm/test/Transforms/LoopIdiom/cheri-preserve-tags-memcpy.ll index 706cea8c1f738..e6d1ce3859080 100644 --- a/llvm/test/Transforms/LoopIdiom/cheri-preserve-tags-memcpy.ll +++ b/llvm/test/Transforms/LoopIdiom/cheri-preserve-tags-memcpy.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --force-update +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature ; Check that we retain the {must,no}_preserve_cheri_tags attribute when merging memcpy loops. ; FIXME: this does not work as expected with addrspace(200) pointers yet since we need SCEV. ; RUN: sed -e 's/-A200-P200-G200//g' -e 's/.p200/.p0/g' %s | \ @@ -32,9 +32,9 @@ define void @no_preserve(ptr addrspace("A") noalias writeonly %dst, ptr addrspac ; HYBRID-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[COUNT]], 0 ; HYBRID-NEXT: br i1 [[CMP1]], label [[BB1_PREHEADER:%.*]], label [[BB2:%.*]] ; HYBRID: bb1.preheader: -; HYBRID-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[SRC]], i64 16 +; HYBRID-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[SRC]], i64 16 ; HYBRID-NEXT: [[TMP1:%.*]] = shl nuw i64 [[COUNT]], 4 -; HYBRID-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[DST]], ptr align 4 [[UGLYGEP]], i64 [[TMP1]], i1 false) #[[ATTR2:[0-9]+]] +; HYBRID-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[DST]], ptr align 4 [[SCEVGEP]], i64 [[TMP1]], i1 false) #[[ATTR2:[0-9]+]] ; HYBRID-NEXT: br label [[BB2]] ; HYBRID: bb2: ; HYBRID-NEXT: ret void @@ -42,15 +42,12 @@ define void @no_preserve(ptr addrspace("A") noalias writeonly %dst, ptr addrspac ; PURECAP-LABEL: define {{[^@]+}}@no_preserve ; PURECAP-SAME: (ptr addrspace(200) noalias writeonly [[DST:%.*]], ptr addrspace(200) noalias readonly [[SRC:%.*]], i64 [[COUNT:%.*]]) local_unnamed_addr addrspace(200) #[[ATTR0:[0-9]+]] { ; PURECAP-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[COUNT]], 0 -; PURECAP-NEXT: br i1 [[CMP1]], label [[BB1:%.*]], label [[BB2:%.*]] -; PURECAP: bb1: -; PURECAP-NEXT: [[IDX:%.*]] = phi i64 [ [[ADD:%.*]], [[BB1]] ], [ 0, [[TMP0:%.*]] ] -; PURECAP-NEXT: [[LDST:%.*]] = getelementptr [[STRUCT_WOMBAT:%.*]], ptr addrspace(200) [[DST]], i64 [[IDX]] -; PURECAP-NEXT: [[ADD]] = add nuw nsw i64 [[IDX]], 1 -; PURECAP-NEXT: [[LSRC:%.*]] = getelementptr [[STRUCT_WOMBAT]], ptr addrspace(200) [[SRC]], i64 [[ADD]] -; PURECAP-NEXT: tail call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) noundef nonnull align 16 dereferenceable(16) [[LDST]], ptr addrspace(200) noundef nonnull align 4 dereferenceable(16) [[LSRC]], i64 16, i1 false) #[[ATTR2:[0-9]+]] -; PURECAP-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ADD]], [[COUNT]] -; PURECAP-NEXT: br i1 [[CMP2]], label [[BB1]], label [[BB2]] +; PURECAP-NEXT: br i1 [[CMP1]], label [[BB1_PREHEADER:%.*]], label [[BB2:%.*]] +; PURECAP: bb1.preheader: +; PURECAP-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr addrspace(200) [[SRC]], i64 16 +; PURECAP-NEXT: [[TMP1:%.*]] = shl nuw i64 [[COUNT]], 4 +; PURECAP-NEXT: call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 [[DST]], ptr addrspace(200) align 4 [[SCEVGEP]], i64 [[TMP1]], i1 false) #[[ATTR2:[0-9]+]] +; PURECAP-NEXT: br label [[BB2]] ; PURECAP: bb2: ; PURECAP-NEXT: ret void ; @@ -82,9 +79,9 @@ define void @must_preserve(ptr addrspace("A") noalias writeonly %dst, ptr addrsp ; HYBRID-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[COUNT]], 0 ; HYBRID-NEXT: br i1 [[CMP1]], label [[BB1_PREHEADER:%.*]], label [[BB2:%.*]] ; HYBRID: bb1.preheader: -; HYBRID-NEXT: [[UGLYGEP:%.*]] = getelementptr i8, ptr [[SRC]], i64 16 +; HYBRID-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr [[SRC]], i64 16 ; HYBRID-NEXT: [[TMP1:%.*]] = shl nuw i64 [[COUNT]], 4 -; HYBRID-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[DST]], ptr align 4 [[UGLYGEP]], i64 [[TMP1]], i1 false) #[[ATTR3:[0-9]+]] +; HYBRID-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 16 [[DST]], ptr align 4 [[SCEVGEP]], i64 [[TMP1]], i1 false) #[[ATTR3:[0-9]+]] ; HYBRID-NEXT: br label [[BB2]] ; HYBRID: bb2: ; HYBRID-NEXT: ret void @@ -92,15 +89,12 @@ define void @must_preserve(ptr addrspace("A") noalias writeonly %dst, ptr addrsp ; PURECAP-LABEL: define {{[^@]+}}@must_preserve ; PURECAP-SAME: (ptr addrspace(200) noalias writeonly [[DST:%.*]], ptr addrspace(200) noalias readonly [[SRC:%.*]], i64 [[COUNT:%.*]]) local_unnamed_addr addrspace(200) #[[ATTR0]] { ; PURECAP-NEXT: [[CMP1:%.*]] = icmp sgt i64 [[COUNT]], 0 -; PURECAP-NEXT: br i1 [[CMP1]], label [[BB1:%.*]], label [[BB2:%.*]] -; PURECAP: bb1: -; PURECAP-NEXT: [[IDX:%.*]] = phi i64 [ [[ADD:%.*]], [[BB1]] ], [ 0, [[TMP0:%.*]] ] -; PURECAP-NEXT: [[LDST:%.*]] = getelementptr [[STRUCT_WOMBAT:%.*]], ptr addrspace(200) [[DST]], i64 [[IDX]] -; PURECAP-NEXT: [[ADD]] = add nuw nsw i64 [[IDX]], 1 -; PURECAP-NEXT: [[LSRC:%.*]] = getelementptr [[STRUCT_WOMBAT]], ptr addrspace(200) [[SRC]], i64 [[ADD]] -; PURECAP-NEXT: tail call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) noundef nonnull align 16 dereferenceable(16) [[LDST]], ptr addrspace(200) noundef nonnull align 4 dereferenceable(16) [[LSRC]], i64 16, i1 false) #[[ATTR3:[0-9]+]] -; PURECAP-NEXT: [[CMP2:%.*]] = icmp slt i64 [[ADD]], [[COUNT]] -; PURECAP-NEXT: br i1 [[CMP2]], label [[BB1]], label [[BB2]] +; PURECAP-NEXT: br i1 [[CMP1]], label [[BB1_PREHEADER:%.*]], label [[BB2:%.*]] +; PURECAP: bb1.preheader: +; PURECAP-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, ptr addrspace(200) [[SRC]], i64 16 +; PURECAP-NEXT: [[TMP1:%.*]] = shl nuw i64 [[COUNT]], 4 +; PURECAP-NEXT: call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 [[DST]], ptr addrspace(200) align 4 [[SCEVGEP]], i64 [[TMP1]], i1 false) #[[ATTR3:[0-9]+]] +; PURECAP-NEXT: br label [[BB2]] ; PURECAP: bb2: ; PURECAP-NEXT: ret void ; diff --git a/llvm/test/Transforms/LoopIdiom/cheri-preserve-tags-store.ll b/llvm/test/Transforms/LoopIdiom/cheri-preserve-tags-store.ll index b99cd3366dcc7..5d03e1dd8d8bb 100644 --- a/llvm/test/Transforms/LoopIdiom/cheri-preserve-tags-store.ll +++ b/llvm/test/Transforms/LoopIdiom/cheri-preserve-tags-store.ll @@ -1,4 +1,4 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature --force-update +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature ; We should be setting no_preserve_cheri_tags for loops that copy integers, and must_preserve_cheri_tags for capability copies. ; FIXME: this does not work with addrspace(200) pointers yet since we need SCEV. ; RUN: sed -e 's/-A200-P200-G200//g' %s | opt --passes='require,loop(loop-idiom,loop-deletion),simplifycfg' -aa-pipeline=basic-aa -S | \ @@ -24,17 +24,7 @@ define void @get_state(ptr addrspace("A") nocapture noalias %state) addrspace("P ; PURECAP-LABEL: define {{[^@]+}}@get_state ; PURECAP-SAME: (ptr addrspace(200) noalias nocapture [[STATE:%.*]]) addrspace(200) { ; PURECAP-NEXT: entry: -; PURECAP-NEXT: br label [[FOR_BODY:%.*]] -; PURECAP: for.body: -; PURECAP-NEXT: [[I_08:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] -; PURECAP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [25 x i32], ptr addrspace(200) @nocap, i64 0, i64 [[I_08]] -; PURECAP-NEXT: [[TMP0:%.*]] = load i32, ptr addrspace(200) [[ARRAYIDX]], align 4 -; PURECAP-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [[STRUCT_STATE:%.*]], ptr addrspace(200) [[STATE]], i64 0, i32 0, i64 [[I_08]] -; PURECAP-NEXT: store i32 [[TMP0]], ptr addrspace(200) [[ARRAYIDX2]], align 4 -; PURECAP-NEXT: [[INC]] = add nuw nsw i64 [[I_08]], 1 -; PURECAP-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INC]], 25 -; PURECAP-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] -; PURECAP: for.end: +; PURECAP-NEXT: call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 4 [[STATE]], ptr addrspace(200) align 4 @nocap, i64 100, i1 false) #[[ATTR1:[0-9]+]] ; PURECAP-NEXT: ret void ; entry: @@ -67,17 +57,7 @@ define void @get_cap_state(ptr addrspace("A") nocapture noalias %state) addrspac ; PURECAP-LABEL: define {{[^@]+}}@get_cap_state ; PURECAP-SAME: (ptr addrspace(200) noalias nocapture [[STATE:%.*]]) addrspace(200) { ; PURECAP-NEXT: entry: -; PURECAP-NEXT: br label [[FOR_BODY:%.*]] -; PURECAP: for.body: -; PURECAP-NEXT: [[I_08:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INC:%.*]], [[FOR_BODY]] ] -; PURECAP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [25 x ptr addrspace(200)], ptr addrspace(200) @cap, i64 0, i64 [[I_08]] -; PURECAP-NEXT: [[TMP0:%.*]] = load ptr addrspace(200), ptr addrspace(200) [[ARRAYIDX]], align 16 -; PURECAP-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [[STRUCT_CAPSTATE:%.*]], ptr addrspace(200) [[STATE]], i64 0, i32 0, i64 [[I_08]] -; PURECAP-NEXT: store ptr addrspace(200) [[TMP0]], ptr addrspace(200) [[ARRAYIDX2]], align 16 -; PURECAP-NEXT: [[INC]] = add nuw nsw i64 [[I_08]], 1 -; PURECAP-NEXT: [[EXITCOND:%.*]] = icmp ne i64 [[INC]], 25 -; PURECAP-NEXT: br i1 [[EXITCOND]], label [[FOR_BODY]], label [[FOR_END:%.*]] -; PURECAP: for.end: +; PURECAP-NEXT: call void @llvm.memcpy.p200.p200.i64(ptr addrspace(200) align 16 [[STATE]], ptr addrspace(200) align 16 @cap, i64 400, i1 false) #[[ATTR2:[0-9]+]] ; PURECAP-NEXT: ret void ; entry: