Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -174,15 +174,21 @@ if (*CopyDstAlign < Size || *CopySrcAlign < Size) return nullptr; - // Use an integer load+store unless we can find something better. unsigned SrcAddrSp = cast(MI->getArgOperand(1)->getType())->getAddressSpace(); unsigned DstAddrSp = - cast(MI->getArgOperand(0)->getType())->getAddressSpace(); - - IntegerType* IntType = IntegerType::get(MI->getContext(), Size<<3); - Type *NewSrcPtrTy = PointerType::get(IntType, SrcAddrSp); - Type *NewDstPtrTy = PointerType::get(IntType, DstAddrSp); + cast(MI->getArgOperand(0)->getType())->getAddressSpace(); + + // Replace memcpy with an vector load/store, to preserve byte-wise + // poison. + // TODO: Atomic load/store does not support vectors, so keep using integers + // for now. + LLVMContext &Context = MI->getContext(); + Type *NewValTy = isa(MI) || Size == 1 + ? (Type*)Type::getIntNTy(Context, Size * 8) + : FixedVectorType::get(Type::getInt8Ty(Context), Size); + Type *NewSrcPtrTy = PointerType::get(NewValTy, SrcAddrSp); + Type *NewDstPtrTy = PointerType::get(NewValTy, DstAddrSp); // If the memcpy has metadata describing the members, see if we can get the // TBAA tag describing our copy. @@ -203,7 +209,7 @@ Value *Src = Builder.CreateBitCast(MI->getArgOperand(1), NewSrcPtrTy); Value *Dest = Builder.CreateBitCast(MI->getArgOperand(0), NewDstPtrTy); - LoadInst *L = Builder.CreateLoad(IntType, Src); + LoadInst *L = Builder.CreateLoad(NewValTy, Src); // Alignment from the mem intrinsic will be better, so use it. L->setAlignment(*CopySrcAlign); if (CopyMD) Index: llvm/test/Transforms/Inline/byval-tail-call.ll =================================================================== --- llvm/test/Transforms/Inline/byval-tail-call.ll +++ llvm/test/Transforms/Inline/byval-tail-call.ll @@ -23,8 +23,8 @@ ; CHECK-LABEL: @foo( ; CHECK-NEXT: [[X1:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X1]]) -; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[X:%.*]], align 1 -; CHECK-NEXT: store i32 [[TMP2]], ptr [[X1]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[X:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> [[TMP1]], ptr [[X1]], align 4 ; CHECK-NEXT: call void @ext(ptr nonnull [[X1]]) ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X1]]) ; CHECK-NEXT: ret void @@ -43,8 +43,8 @@ ; CHECK-LABEL: @frob( ; CHECK-NEXT: [[X1:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X1]]) -; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[X:%.*]], align 1 -; CHECK-NEXT: store i32 [[TMP2]], ptr [[X1]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[X:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> [[TMP1]], ptr [[X1]], align 4 ; CHECK-NEXT: call void @ext(ptr nonnull [[X1]]) ; CHECK-NEXT: tail call void @ext(ptr null) ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X1]]) @@ -72,8 +72,8 @@ ; CHECK-LABEL: @foobar( ; CHECK-NEXT: [[X1:%.*]] = alloca i32, align 4 ; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[X1]]) -; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[X:%.*]], align 1 -; CHECK-NEXT: store i32 [[TMP2]], ptr [[X1]], align 4 +; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[X:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> [[TMP1]], ptr [[X1]], align 4 ; CHECK-NEXT: tail call void @ext2(ptr nonnull byval(i32) [[X1]]) ; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 4, ptr nonnull [[X1]]) ; CHECK-NEXT: ret void Index: llvm/test/Transforms/InstCombine/alloca.ll =================================================================== --- llvm/test/Transforms/InstCombine/alloca.ll +++ llvm/test/Transforms/InstCombine/alloca.ll @@ -189,8 +189,8 @@ ; ALL-LABEL: @test9( ; ALL-NEXT: entry: ; ALL-NEXT: [[ARGMEM:%.*]] = alloca inalloca <{ [[STRUCT_TYPE:%.*]] }>, align 8 -; ALL-NEXT: [[TMP0:%.*]] = load i64, ptr [[A:%.*]], align 4 -; ALL-NEXT: store i64 [[TMP0]], ptr [[ARGMEM]], align 8 +; ALL-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[A:%.*]], align 4 +; ALL-NEXT: store <8 x i8> [[TMP0]], ptr [[ARGMEM]], align 8 ; ALL-NEXT: call void @test9_aux(ptr nonnull inalloca(<{ [[STRUCT_TYPE]] }>) [[ARGMEM]]) ; ALL-NEXT: ret void ; Index: llvm/test/Transforms/InstCombine/bcopy.ll =================================================================== --- llvm/test/Transforms/InstCombine/bcopy.ll +++ llvm/test/Transforms/InstCombine/bcopy.ll @@ -5,8 +5,8 @@ define void @bcopy_memmove(ptr nocapture readonly %a, ptr nocapture %b) { ; CHECK-LABEL: @bcopy_memmove( -; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[A:%.*]], align 1 -; CHECK-NEXT: store i64 [[TMP3]], ptr [[B:%.*]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[A:%.*]], align 1 +; CHECK-NEXT: store <8 x i8> [[TMP1]], ptr [[B:%.*]], align 1 ; CHECK-NEXT: ret void ; tail call void @bcopy(ptr %a, ptr %b, i32 8) @@ -15,7 +15,7 @@ define void @bcopy_memmove2(ptr nocapture readonly %a, ptr nocapture %b, i32 %len) { ; CHECK-LABEL: @bcopy_memmove2( -; CHECK-NEXT: call void @llvm.memmove.p0.p0.i32(ptr align 1 [[B:%.*]], ptr align 1 [[A:%.*]], i32 [[LEN:%.*]], i1 false) +; CHECK-NEXT: tail call void @llvm.memmove.p0.p0.i32(ptr align 1 [[B:%.*]], ptr align 1 [[A:%.*]], i32 [[LEN:%.*]], i1 false) ; CHECK-NEXT: ret void ; tail call void @bcopy(ptr %a, ptr %b, i32 %len) Index: llvm/test/Transforms/InstCombine/mem-par-metadata-memcpy.ll =================================================================== --- llvm/test/Transforms/InstCombine/mem-par-metadata-memcpy.ll +++ llvm/test/Transforms/InstCombine/mem-par-metadata-memcpy.ll @@ -25,8 +25,8 @@ ; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[OUT:%.*]], i64 [[I_0]] ; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[I_0]], [[SIZE]] ; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[OUT]], i64 [[ADD]] -; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[ARRAYIDX1]], align 1, !llvm.access.group [[ACC_GRP0:![0-9]+]] -; CHECK-NEXT: store i16 [[TMP0]], ptr [[ARRAYIDX]], align 1, !llvm.access.group [[ACC_GRP0]] +; CHECK-NEXT: [[TMP0:%.*]] = load <2 x i8>, ptr [[ARRAYIDX1]], align 1, !llvm.access.group [[ACC_GRP0:![0-9]+]] +; CHECK-NEXT: store <2 x i8> [[TMP0]], ptr [[ARRAYIDX]], align 1, !llvm.access.group [[ACC_GRP0]] ; CHECK-NEXT: br label [[FOR_INC]] ; CHECK: for.inc: ; CHECK-NEXT: [[ADD2]] = add nuw nsw i64 [[I_0]], 2 Index: llvm/test/Transforms/InstCombine/memccpy.ll =================================================================== --- llvm/test/Transforms/InstCombine/memccpy.ll +++ llvm/test/Transforms/InstCombine/memccpy.ll @@ -10,9 +10,9 @@ define ptr @memccpy_to_memcpy(ptr %dst) { ; CHECK-LABEL: @memccpy_to_memcpy( -; CHECK-NEXT: store i64 8245940763182785896, ptr [[DST:%.*]], align 1 -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 8 -; CHECK-NEXT: ret ptr [[TMP2]] +; CHECK-NEXT: store <8 x i8> , ptr [[DST:%.*]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 8 +; CHECK-NEXT: ret ptr [[TMP1]] ; %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 12) ; 114 is 'r' ret ptr %call @@ -20,9 +20,9 @@ define ptr @memccpy_to_memcpy2(ptr %dst) { ; CHECK-LABEL: @memccpy_to_memcpy2( -; CHECK-NEXT: store i64 8245940763182785896, ptr [[DST:%.*]], align 1 -; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 8 -; CHECK-NEXT: ret ptr [[TMP2]] +; CHECK-NEXT: store <8 x i8> , ptr [[DST:%.*]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 8 +; CHECK-NEXT: ret ptr [[TMP1]] ; %call = call ptr @memccpy(ptr %dst, ptr @hello, i32 114, i64 8); ; 114 is 'r' ret ptr %call Index: llvm/test/Transforms/InstCombine/memcpy-to-load.ll =================================================================== --- llvm/test/Transforms/InstCombine/memcpy-to-load.ll +++ llvm/test/Transforms/InstCombine/memcpy-to-load.ll @@ -20,8 +20,8 @@ define void @copy_2_bytes(ptr %d, ptr %s) { ; CHECK-LABEL: @copy_2_bytes( -; CHECK-NEXT: [[TMP3:%.*]] = load i16, ptr [[S:%.*]], align 1 -; CHECK-NEXT: store i16 [[TMP3]], ptr [[D:%.*]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = load <2 x i8>, ptr [[S:%.*]], align 1 +; CHECK-NEXT: store <2 x i8> [[TMP1]], ptr [[D:%.*]], align 1 ; CHECK-NEXT: ret void ; call void @llvm.memcpy.p0.p0.i32(ptr %d, ptr %s, i32 2, i1 false) @@ -41,8 +41,8 @@ define void @copy_4_bytes(ptr %d, ptr %s) { ; CHECK-LABEL: @copy_4_bytes( -; CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[S:%.*]], align 1 -; CHECK-NEXT: store i32 [[TMP3]], ptr [[D:%.*]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i8>, ptr [[S:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> [[TMP1]], ptr [[D:%.*]], align 1 ; CHECK-NEXT: ret void ; call void @llvm.memcpy.p0.p0.i32(ptr %d, ptr %s, i32 4, i1 false) @@ -62,8 +62,8 @@ define void @copy_8_bytes(ptr %d, ptr %s) { ; CHECK-LABEL: @copy_8_bytes( -; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[S:%.*]], align 1 -; CHECK-NEXT: store i64 [[TMP3]], ptr [[D:%.*]], align 1 +; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[S:%.*]], align 1 +; CHECK-NEXT: store <8 x i8> [[TMP1]], ptr [[D:%.*]], align 1 ; CHECK-NEXT: ret void ; call void @llvm.memcpy.p0.p0.i32(ptr %d, ptr %s, i32 8, i1 false) Index: llvm/test/Transforms/InstCombine/memmove.ll =================================================================== --- llvm/test/Transforms/InstCombine/memmove.ll +++ llvm/test/Transforms/InstCombine/memmove.ll @@ -28,9 +28,9 @@ define i32 @test3(ptr %target) { ; arg: ptr> [#uses=1] ; CHECK-LABEL: @test3( -; CHECK-NEXT: store i16 104, ptr [[TARGET:%.*]], align 2 -; CHECK-NEXT: store i32 7103848, ptr [[TARGET]], align 4 -; CHECK-NEXT: store i64 33037504440198504, ptr [[TARGET]], align 8 +; CHECK-NEXT: store <2 x i8> , ptr [[TARGET:%.*]], align 2 +; CHECK-NEXT: store <4 x i8> , ptr [[TARGET]], align 4 +; CHECK-NEXT: store <8 x i8> , ptr [[TARGET]], align 8 ; CHECK-NEXT: ret i32 0 ; %h_p = getelementptr [2 x i8], ptr @h, i32 0, i32 0 ; [#uses=1] Index: llvm/test/Transforms/InstCombine/mempcpy.ll =================================================================== --- llvm/test/Transforms/InstCombine/mempcpy.ll +++ llvm/test/Transforms/InstCombine/mempcpy.ll @@ -3,7 +3,7 @@ define ptr @memcpy_nonconst_n(ptr %d, ptr nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcpy_nonconst_n( -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[D:%.*]], ptr align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[D:%.*]], ptr align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 [[N]] ; CHECK-NEXT: ret ptr [[TMP1]] ; @@ -13,7 +13,7 @@ define ptr @memcpy_nonconst_n_copy_attrs(ptr %d, ptr nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcpy_nonconst_n_copy_attrs( -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 dereferenceable(16) [[D:%.*]], ptr align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 1 dereferenceable(16) [[D:%.*]], ptr align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 [[N]] ; CHECK-NEXT: ret ptr [[TMP1]] ; @@ -32,10 +32,10 @@ define ptr @memcpy_small_const_n(ptr %d, ptr nocapture readonly %s) { ; CHECK-LABEL: @memcpy_small_const_n( -; CHECK-NEXT: [[TMP3:%.*]] = load i64, ptr [[S:%.*]], align 1 -; CHECK-NEXT: store i64 [[TMP3]], ptr [[D:%.*]], align 1 -; CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 8 -; CHECK-NEXT: ret ptr [[TMP4]] +; CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr [[S:%.*]], align 1 +; CHECK-NEXT: store <8 x i8> [[TMP1]], ptr [[D:%.*]], align 1 +; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 8 +; CHECK-NEXT: ret ptr [[TMP2]] ; %r = tail call ptr @mempcpy(ptr %d, ptr %s, i64 8) ret ptr %r @@ -43,7 +43,7 @@ define ptr @memcpy_big_const_n(ptr %d, ptr nocapture readonly %s) { ; CHECK-LABEL: @memcpy_big_const_n( -; CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(1024) [[D:%.*]], ptr noundef nonnull align 1 dereferenceable(1024) [[S:%.*]], i64 1024, i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(1024) [[D:%.*]], ptr noundef nonnull align 1 dereferenceable(1024) [[S:%.*]], i64 1024, i1 false) ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[D]], i64 1024 ; CHECK-NEXT: ret ptr [[TMP1]] ; @@ -64,8 +64,8 @@ define ptr @memcpy_no_simplify1(ptr %d, ptr nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcpy_no_simplify1( -; CHECK-NEXT: %r = musttail call ptr @mempcpy(ptr %d, ptr %s, i64 %n) -; CHECK-NEXT: ret ptr %r +; CHECK-NEXT: [[R:%.*]] = musttail call ptr @mempcpy(ptr [[D:%.*]], ptr [[S:%.*]], i64 [[N:%.*]]) +; CHECK-NEXT: ret ptr [[R]] ; %r = musttail call ptr @mempcpy(ptr %d, ptr %s, i64 %n) ret ptr %r Index: llvm/test/Transforms/InstCombine/snprintf-2.ll =================================================================== --- llvm/test/Transforms/InstCombine/snprintf-2.ll +++ llvm/test/Transforms/InstCombine/snprintf-2.ll @@ -20,57 +20,31 @@ ; to 0 are transformed to memcpy. define void @fold_snprintf_fmt() { -; BE-LABEL: @fold_snprintf_fmt( -; BE-NEXT: [[PDIMAX:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2147483647), align 8 -; BE-NEXT: store i32 825373440, ptr [[PDIMAX]], align 1 -; BE-NEXT: store i32 3, ptr @asiz, align 4 -; BE-NEXT: [[PD5:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 5), align 8 -; BE-NEXT: store i32 825373440, ptr [[PD5]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 5), align 4 -; BE-NEXT: [[PD4:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 4), align 8 -; BE-NEXT: store i32 825373440, ptr [[PD4]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 4), align 4 -; BE-NEXT: [[PD3:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 3), align 8 -; BE-NEXT: store i16 12594, ptr [[PD3]], align 1 -; BE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[PD3]], i64 2 -; BE-NEXT: store i8 0, ptr [[ENDPTR]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 3), align 4 -; BE-NEXT: [[PD2:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2), align 8 -; BE-NEXT: store i8 49, ptr [[PD2]], align 1 -; BE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[PD2]], i64 1 -; BE-NEXT: store i8 0, ptr [[ENDPTR1]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 2), align 4 -; BE-NEXT: [[PD1:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 1), align 8 -; BE-NEXT: store i8 0, ptr [[PD1]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 1), align 4 -; BE-NEXT: store i32 3, ptr @asiz, align 4 -; BE-NEXT: ret void -; -; LE-LABEL: @fold_snprintf_fmt( -; LE-NEXT: [[PDIMAX:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2147483647), align 8 -; LE-NEXT: store i32 3355185, ptr [[PDIMAX]], align 1 -; LE-NEXT: store i32 3, ptr @asiz, align 4 -; LE-NEXT: [[PD5:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 5), align 8 -; LE-NEXT: store i32 3355185, ptr [[PD5]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 5), align 4 -; LE-NEXT: [[PD4:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 4), align 8 -; LE-NEXT: store i32 3355185, ptr [[PD4]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 4), align 4 -; LE-NEXT: [[PD3:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 3), align 8 -; LE-NEXT: store i16 12849, ptr [[PD3]], align 1 -; LE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[PD3]], i64 2 -; LE-NEXT: store i8 0, ptr [[ENDPTR]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 3), align 4 -; LE-NEXT: [[PD2:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2), align 8 -; LE-NEXT: store i8 49, ptr [[PD2]], align 1 -; LE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[PD2]], i64 1 -; LE-NEXT: store i8 0, ptr [[ENDPTR1]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 2), align 4 -; LE-NEXT: [[PD1:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 1), align 8 -; LE-NEXT: store i8 0, ptr [[PD1]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 1), align 4 -; LE-NEXT: store i32 3, ptr @asiz, align 4 -; LE-NEXT: ret void +; ANY-LABEL: @fold_snprintf_fmt( +; ANY-NEXT: [[PDIMAX:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2147483647), align 8 +; ANY-NEXT: store <4 x i8> , ptr [[PDIMAX]], align 1 +; ANY-NEXT: store i32 3, ptr @asiz, align 4 +; ANY-NEXT: [[PD5:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 5), align 8 +; ANY-NEXT: store <4 x i8> , ptr [[PD5]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 5), align 4 +; ANY-NEXT: [[PD4:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 4), align 8 +; ANY-NEXT: store <4 x i8> , ptr [[PD4]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 4), align 4 +; ANY-NEXT: [[PD3:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 3), align 8 +; ANY-NEXT: store <2 x i8> , ptr [[PD3]], align 1 +; ANY-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[PD3]], i64 2 +; ANY-NEXT: store i8 0, ptr [[ENDPTR]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 3), align 4 +; ANY-NEXT: [[PD2:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2), align 8 +; ANY-NEXT: store i8 49, ptr [[PD2]], align 1 +; ANY-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[PD2]], i64 1 +; ANY-NEXT: store i8 0, ptr [[ENDPTR1]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 2), align 4 +; ANY-NEXT: [[PD1:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 1), align 8 +; ANY-NEXT: store i8 0, ptr [[PD1]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 1), align 4 +; ANY-NEXT: store i32 3, ptr @asiz, align 4 +; ANY-NEXT: ret void ; %pdimax = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 2147483647) @@ -130,3 +104,6 @@ ret void } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; BE: {{.*}} +; LE: {{.*}} Index: llvm/test/Transforms/InstCombine/snprintf-3.ll =================================================================== --- llvm/test/Transforms/InstCombine/snprintf-3.ll +++ llvm/test/Transforms/InstCombine/snprintf-3.ll @@ -21,57 +21,31 @@ ; to 0 are transformed to memcpy. define void @fold_snprintf_pcnt_s() { -; BE-LABEL: @fold_snprintf_pcnt_s( -; BE-NEXT: [[PDIMAX:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2147483647), align 8 -; BE-NEXT: store i32 825373440, ptr [[PDIMAX]], align 1 -; BE-NEXT: store i32 3, ptr @asiz, align 4 -; BE-NEXT: [[PD5:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 5), align 8 -; BE-NEXT: store i32 825373440, ptr [[PD5]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 5), align 4 -; BE-NEXT: [[PD4:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 4), align 8 -; BE-NEXT: store i32 825373440, ptr [[PD4]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 4), align 4 -; BE-NEXT: [[PD3:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 3), align 8 -; BE-NEXT: store i16 12594, ptr [[PD3]], align 1 -; BE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[PD3]], i64 2 -; BE-NEXT: store i8 0, ptr [[ENDPTR]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 3), align 4 -; BE-NEXT: [[PD2:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2), align 8 -; BE-NEXT: store i8 49, ptr [[PD2]], align 1 -; BE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[PD2]], i64 1 -; BE-NEXT: store i8 0, ptr [[ENDPTR1]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 2), align 4 -; BE-NEXT: [[PD1:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 1), align 8 -; BE-NEXT: store i8 0, ptr [[PD1]], align 1 -; BE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 1), align 4 -; BE-NEXT: store i32 3, ptr @asiz, align 4 -; BE-NEXT: ret void -; -; LE-LABEL: @fold_snprintf_pcnt_s( -; LE-NEXT: [[PDIMAX:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2147483647), align 8 -; LE-NEXT: store i32 3355185, ptr [[PDIMAX]], align 1 -; LE-NEXT: store i32 3, ptr @asiz, align 4 -; LE-NEXT: [[PD5:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 5), align 8 -; LE-NEXT: store i32 3355185, ptr [[PD5]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 5), align 4 -; LE-NEXT: [[PD4:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 4), align 8 -; LE-NEXT: store i32 3355185, ptr [[PD4]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 4), align 4 -; LE-NEXT: [[PD3:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 3), align 8 -; LE-NEXT: store i16 12849, ptr [[PD3]], align 1 -; LE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[PD3]], i64 2 -; LE-NEXT: store i8 0, ptr [[ENDPTR]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 3), align 4 -; LE-NEXT: [[PD2:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2), align 8 -; LE-NEXT: store i8 49, ptr [[PD2]], align 1 -; LE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[PD2]], i64 1 -; LE-NEXT: store i8 0, ptr [[ENDPTR1]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 2), align 4 -; LE-NEXT: [[PD1:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 1), align 8 -; LE-NEXT: store i8 0, ptr [[PD1]], align 1 -; LE-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 1), align 4 -; LE-NEXT: store i32 3, ptr @asiz, align 4 -; LE-NEXT: ret void +; ANY-LABEL: @fold_snprintf_pcnt_s( +; ANY-NEXT: [[PDIMAX:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2147483647), align 8 +; ANY-NEXT: store <4 x i8> , ptr [[PDIMAX]], align 1 +; ANY-NEXT: store i32 3, ptr @asiz, align 4 +; ANY-NEXT: [[PD5:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 5), align 8 +; ANY-NEXT: store <4 x i8> , ptr [[PD5]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 5), align 4 +; ANY-NEXT: [[PD4:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 4), align 8 +; ANY-NEXT: store <4 x i8> , ptr [[PD4]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 4), align 4 +; ANY-NEXT: [[PD3:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 3), align 8 +; ANY-NEXT: store <2 x i8> , ptr [[PD3]], align 1 +; ANY-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[PD3]], i64 2 +; ANY-NEXT: store i8 0, ptr [[ENDPTR]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 3), align 4 +; ANY-NEXT: [[PD2:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 2), align 8 +; ANY-NEXT: store i8 49, ptr [[PD2]], align 1 +; ANY-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[PD2]], i64 1 +; ANY-NEXT: store i8 0, ptr [[ENDPTR1]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 2), align 4 +; ANY-NEXT: [[PD1:%.*]] = load ptr, ptr getelementptr inbounds ([0 x ptr], ptr @adst, i64 0, i64 1), align 8 +; ANY-NEXT: store i8 0, ptr [[PD1]], align 1 +; ANY-NEXT: store i32 3, ptr getelementptr inbounds ([0 x i32], ptr @asiz, i64 0, i64 1), align 4 +; ANY-NEXT: store i32 3, ptr @asiz, align 4 +; ANY-NEXT: ret void ; %pdimax = load ptr, ptr getelementptr ([0 x ptr], ptr @adst, i32 0, i32 2147483647) @@ -131,3 +105,6 @@ ret void } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; BE: {{.*}} +; LE: {{.*}} Index: llvm/test/Transforms/InstCombine/snprintf.ll =================================================================== --- llvm/test/Transforms/InstCombine/snprintf.ll +++ llvm/test/Transforms/InstCombine/snprintf.ll @@ -76,7 +76,7 @@ define void @test_correct_copy(ptr %buf) #0 { ; CHECK-LABEL: @test_correct_copy( -; CHECK-NEXT: store i32 7500915, ptr [[BUF:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> , ptr [[BUF:%.*]], align 1 ; CHECK-NEXT: ret void ; %call = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %buf, i64 32, ptr @.str) #2 @@ -130,7 +130,7 @@ define i32 @test_str_ok_size(ptr %buf) #0 { ; CHECK-LABEL: @test_str_ok_size( -; CHECK-NEXT: store i32 7500915, ptr [[BUF:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> , ptr [[BUF:%.*]], align 1 ; CHECK-NEXT: ret i32 3 ; %call = call i32 (ptr, i64, ptr, ...) @snprintf(ptr %buf, i64 32, ptr @.str.3, ptr @.str) #2 @@ -159,7 +159,7 @@ ; snprintf(buf, 32, "%s", "str") -> memcpy -> store define i32 @test_str_ok_size_tail2(ptr %buf) { ; CHECK-LABEL: @test_str_ok_size_tail2( -; CHECK-NEXT: store i32 7500915, ptr [[BUF:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> , ptr [[BUF:%.*]], align 1 ; CHECK-NEXT: ret i32 3 ; %1 = tail call i32 (ptr, i64, ptr, ...) @snprintf(ptr %buf, i64 8, ptr @.str.3, ptr @.str) Index: llvm/test/Transforms/InstCombine/sprintf-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/sprintf-1.ll +++ llvm/test/Transforms/InstCombine/sprintf-1.ll @@ -105,7 +105,6 @@ ; NOSTPCPY-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1 ; NOSTPCPY-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[DST:%.*]], ptr align 1 [[STR]], i32 [[LENINC]], i1 false) ; NOSTPCPY-NEXT: ret i32 [[STRLEN]] -; %r = call i32 (ptr, ptr, ...) @sprintf(ptr %dst, ptr @percent_s, ptr %str) ret i32 %r } Index: llvm/test/Transforms/InstCombine/stpncpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/stpncpy-1.ll +++ llvm/test/Transforms/InstCombine/stpncpy-1.ll @@ -138,37 +138,21 @@ ; of strncpy(D, "4", N) and the result folded to D + (N != 0). define void @fold_stpncpy_s1(ptr %dst) { -; BE-LABEL: @fold_stpncpy_s1( -; BE-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) -; BE-NEXT: store i8 52, ptr [[DST]], align 1 -; BE-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) -; BE-NEXT: store i16 13312, ptr [[DST]], align 1 -; BE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(3) @str.6, i64 3, i1 false) -; BE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.7, i64 9, i1 false) -; BE-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) -; BE-NEXT: ret void -; -; LE-LABEL: @fold_stpncpy_s1( -; LE-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) -; LE-NEXT: store i8 52, ptr [[DST]], align 1 -; LE-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) -; LE-NEXT: store i16 52, ptr [[DST]], align 1 -; LE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(3) @str.6, i64 3, i1 false) -; LE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.7, i64 9, i1 false) -; LE-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) -; LE-NEXT: ret void +; ANY-LABEL: @fold_stpncpy_s1( +; ANY-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) +; ANY-NEXT: store i8 52, ptr [[DST]], align 1 +; ANY-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) +; ANY-NEXT: store <2 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(3) @str.6, i64 3, i1 false) +; ANY-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.7, i64 9, i1 false) +; ANY-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) +; ANY-NEXT: ret void ; %ps1 = getelementptr [5 x i8], ptr @s4, i32 0, i32 3 @@ -201,43 +185,24 @@ ; of strncpy(D, "1234", N) and the result folded to D + min(4, N). define void @fold_stpncpy_s4(ptr %dst, i64 %n) { -; BE-LABEL: @fold_stpncpy_s4( -; BE-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) -; BE-NEXT: store i8 49, ptr [[DST]], align 1 -; BE-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) -; BE-NEXT: store i16 12594, ptr [[DST]], align 1 -; BE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 3, i1 false) -; BE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) -; BE-NEXT: store i32 825373492, ptr [[DST]], align 1 -; BE-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.8, i64 9, i1 false) -; BE-NEXT: [[ENDPTR3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR3]]) -; BE-NEXT: ret void -; -; LE-LABEL: @fold_stpncpy_s4( -; LE-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) -; LE-NEXT: store i8 49, ptr [[DST]], align 1 -; LE-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) -; LE-NEXT: store i16 12849, ptr [[DST]], align 1 -; LE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 3, i1 false) -; LE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) -; LE-NEXT: store i32 875770417, ptr [[DST]], align 1 -; LE-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.8, i64 9, i1 false) -; LE-NEXT: [[ENDPTR3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR3]]) -; LE-NEXT: ret void +; ANY-LABEL: @fold_stpncpy_s4( +; ANY-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) +; ANY-NEXT: store i8 49, ptr [[DST]], align 1 +; ANY-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) +; ANY-NEXT: store <2 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 3, i1 false) +; ANY-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) +; ANY-NEXT: store <4 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.8, i64 9, i1 false) +; ANY-NEXT: [[ENDPTR3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR3]]) +; ANY-NEXT: ret void ; ; Fold stpncpy(D, "1234", 0) to just D. @@ -309,49 +274,27 @@ ; folded to D + min(4, N). define void @fold_stpncpy_a4(ptr %dst, i64 %n) { -; BE-LABEL: @fold_stpncpy_a4( -; BE-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) -; BE-NEXT: store i8 49, ptr [[DST]], align 1 -; BE-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) -; BE-NEXT: store i16 12594, ptr [[DST]], align 1 -; BE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a4, i64 3, i1 false) -; BE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) -; BE-NEXT: store i32 825373492, ptr [[DST]], align 1 -; BE-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a4, i64 5, i1 false) -; BE-NEXT: [[ENDPTR3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR3]]) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.9, i64 9, i1 false) -; BE-NEXT: [[ENDPTR4:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR4]]) -; BE-NEXT: ret void -; -; LE-LABEL: @fold_stpncpy_a4( -; LE-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) -; LE-NEXT: store i8 49, ptr [[DST]], align 1 -; LE-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) -; LE-NEXT: store i16 12849, ptr [[DST]], align 1 -; LE-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a4, i64 3, i1 false) -; LE-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) -; LE-NEXT: store i32 875770417, ptr [[DST]], align 1 -; LE-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a4, i64 5, i1 false) -; LE-NEXT: [[ENDPTR3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR3]]) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.9, i64 9, i1 false) -; LE-NEXT: [[ENDPTR4:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR4]]) -; LE-NEXT: ret void +; ANY-LABEL: @fold_stpncpy_a4( +; ANY-NEXT: call void @sink(ptr [[DST:%.*]], ptr [[DST]]) +; ANY-NEXT: store i8 49, ptr [[DST]], align 1 +; ANY-NEXT: [[STPNCPY_END:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[STPNCPY_END]]) +; ANY-NEXT: store <2 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: [[ENDPTR:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR]]) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a4, i64 3, i1 false) +; ANY-NEXT: [[ENDPTR1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR1]]) +; ANY-NEXT: store <4 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: [[ENDPTR2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR2]]) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a4, i64 5, i1 false) +; ANY-NEXT: [[ENDPTR3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR3]]) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(9) [[DST]], ptr noundef nonnull align 1 dereferenceable(9) @str.9, i64 9, i1 false) +; ANY-NEXT: [[ENDPTR4:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], ptr nonnull [[ENDPTR4]]) +; ANY-NEXT: ret void ; @@ -451,3 +394,6 @@ ; ANY: attributes #[[ATTR0:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) } ; ANY: attributes #[[ATTR1:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: readwrite) } ;. +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; BE: {{.*}} +; LE: {{.*}} Index: llvm/test/Transforms/InstCombine/strlcpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strlcpy-1.ll +++ llvm/test/Transforms/InstCombine/strlcpy-1.ll @@ -49,29 +49,17 @@ ; and folded to 1 for all values of N. define void @fold_strlcpy_s1(ptr %dst) { -; BE-LABEL: @fold_strlcpy_s1( -; BE-NEXT: call void @sink(ptr [[DST:%.*]], i64 1) -; BE-NEXT: store i8 0, ptr [[DST]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) -; BE-NEXT: store i16 13312, ptr [[DST]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) -; BE-NEXT: store i16 13312, ptr [[DST]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) -; BE-NEXT: store i16 13312, ptr [[DST]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) -; BE-NEXT: ret void -; -; LE-LABEL: @fold_strlcpy_s1( -; LE-NEXT: call void @sink(ptr [[DST:%.*]], i64 1) -; LE-NEXT: store i8 0, ptr [[DST]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) -; LE-NEXT: store i16 52, ptr [[DST]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) -; LE-NEXT: store i16 52, ptr [[DST]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) -; LE-NEXT: store i16 52, ptr [[DST]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) -; LE-NEXT: ret void +; ANY-LABEL: @fold_strlcpy_s1( +; ANY-NEXT: call void @sink(ptr [[DST:%.*]], i64 1) +; ANY-NEXT: store i8 0, ptr [[DST]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; ANY-NEXT: store <2 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; ANY-NEXT: store <2 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; ANY-NEXT: store <2 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 1) +; ANY-NEXT: ret void ; %ps1 = getelementptr [5 x i8], ptr @s4, i32 0, i32 3 @@ -104,53 +92,29 @@ ; all values of N. define void @fold_strlcpy_s5(ptr %dst) { -; BE-LABEL: @fold_strlcpy_s5( -; BE-NEXT: call void @sink(ptr [[DST:%.*]], i64 4) -; BE-NEXT: store i8 0, ptr [[DST]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; BE-NEXT: store i8 49, ptr [[DST]], align 1 -; BE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; BE-NEXT: store i8 0, ptr [[TMP1]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; BE-NEXT: store i16 12594, ptr [[DST]], align 1 -; BE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 -; BE-NEXT: store i8 0, ptr [[TMP2]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(3) @s4, i64 3, i1 false) -; BE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 -; BE-NEXT: store i8 0, ptr [[TMP3]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; BE-NEXT: ret void -; -; LE-LABEL: @fold_strlcpy_s5( -; LE-NEXT: call void @sink(ptr [[DST:%.*]], i64 4) -; LE-NEXT: store i8 0, ptr [[DST]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; LE-NEXT: store i8 49, ptr [[DST]], align 1 -; LE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; LE-NEXT: store i8 0, ptr [[TMP1]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; LE-NEXT: store i16 12849, ptr [[DST]], align 1 -; LE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 -; LE-NEXT: store i8 0, ptr [[TMP2]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(3) @s4, i64 3, i1 false) -; LE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 -; LE-NEXT: store i8 0, ptr [[TMP3]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) -; LE-NEXT: ret void +; ANY-LABEL: @fold_strlcpy_s5( +; ANY-NEXT: call void @sink(ptr [[DST:%.*]], i64 4) +; ANY-NEXT: store i8 0, ptr [[DST]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; ANY-NEXT: store i8 49, ptr [[DST]], align 1 +; ANY-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; ANY-NEXT: store i8 0, ptr [[TMP1]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; ANY-NEXT: store <2 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 2 +; ANY-NEXT: store i8 0, ptr [[TMP2]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(3) [[DST]], ptr noundef nonnull align 1 dereferenceable(3) @s4, i64 3, i1 false) +; ANY-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 3 +; ANY-NEXT: store i8 0, ptr [[TMP3]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @s4, i64 5, i1 false) +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 4) +; ANY-NEXT: ret void ; ; Fold strlcpy(D, "1234", 0) to 4. @@ -278,49 +242,27 @@ ; easy to avoid. define void @fold_strlcpy_a5(ptr %dst, i64 %n) { -; BE-LABEL: @fold_strlcpy_a5( -; BE-NEXT: call void @sink(ptr [[DST:%.*]], i64 5) -; BE-NEXT: store i8 0, ptr [[DST]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; BE-NEXT: store i8 49, ptr [[DST]], align 1 -; BE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; BE-NEXT: store i8 0, ptr [[TMP1]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; BE-NEXT: store i32 825373492, ptr [[DST]], align 1 -; BE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; BE-NEXT: store i8 0, ptr [[TMP2]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) -; BE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 -; BE-NEXT: store i8 0, ptr [[TMP3]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; BE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) -; BE-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 -; BE-NEXT: store i8 0, ptr [[TMP4]], align 1 -; BE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; BE-NEXT: ret void -; -; LE-LABEL: @fold_strlcpy_a5( -; LE-NEXT: call void @sink(ptr [[DST:%.*]], i64 5) -; LE-NEXT: store i8 0, ptr [[DST]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; LE-NEXT: store i8 49, ptr [[DST]], align 1 -; LE-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 -; LE-NEXT: store i8 0, ptr [[TMP1]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; LE-NEXT: store i32 875770417, ptr [[DST]], align 1 -; LE-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 -; LE-NEXT: store i8 0, ptr [[TMP2]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) -; LE-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 -; LE-NEXT: store i8 0, ptr [[TMP3]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; LE-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) -; LE-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 -; LE-NEXT: store i8 0, ptr [[TMP4]], align 1 -; LE-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) -; LE-NEXT: ret void +; ANY-LABEL: @fold_strlcpy_a5( +; ANY-NEXT: call void @sink(ptr [[DST:%.*]], i64 5) +; ANY-NEXT: store i8 0, ptr [[DST]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; ANY-NEXT: store i8 49, ptr [[DST]], align 1 +; ANY-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 1 +; ANY-NEXT: store i8 0, ptr [[TMP1]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; ANY-NEXT: store <4 x i8> , ptr [[DST]], align 1 +; ANY-NEXT: [[TMP2:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 4 +; ANY-NEXT: store i8 0, ptr [[TMP2]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) +; ANY-NEXT: [[TMP3:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 +; ANY-NEXT: store i8 0, ptr [[TMP3]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; ANY-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 1 dereferenceable(5) [[DST]], ptr noundef nonnull align 1 dereferenceable(5) @a5, i64 5, i1 false) +; ANY-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[DST]], i64 5 +; ANY-NEXT: store i8 0, ptr [[TMP4]], align 1 +; ANY-NEXT: call void @sink(ptr nonnull [[DST]], i64 5) +; ANY-NEXT: ret void ; %na5_0 = call i64 @strlcpy(ptr %dst, ptr @a5, i64 0) call void @sink(ptr %dst, i64 %na5_0) @@ -342,3 +284,6 @@ ret void } +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; BE: {{.*}} +; LE: {{.*}} Index: llvm/test/Transforms/InstCombine/strncpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncpy-1.ll +++ llvm/test/Transforms/InstCombine/strncpy-1.ll @@ -161,7 +161,7 @@ define void @test_no_simplify2() { ; CHECK-LABEL: @test_no_simplify2( -; CHECK-NEXT: store i64 478560413032, ptr @a, align 1 +; CHECK-NEXT: store <8 x i8> , ptr @a, align 1 ; CHECK-NEXT: ret void ; Index: llvm/test/Transforms/InstCombine/strncpy-3.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncpy-3.ll +++ llvm/test/Transforms/InstCombine/strncpy-3.ll @@ -11,7 +11,7 @@ define void @fill_with_zeros(ptr %dst) { ; CHECK-LABEL: @fill_with_zeros( -; CHECK-NEXT: store i32 97, ptr [[DST:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> , ptr [[DST:%.*]], align 1 ; CHECK-NEXT: ret void ; tail call ptr @strncpy(ptr %dst, ptr @str, i64 4) @@ -20,7 +20,7 @@ define void @fill_with_zeros2(ptr %dst) { ; CHECK-LABEL: @fill_with_zeros2( -; CHECK-NEXT: store i32 6513249, ptr [[DST:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> , ptr [[DST:%.*]], align 1 ; CHECK-NEXT: ret void ; tail call ptr @strncpy(ptr %dst, ptr @str2, i64 4) @@ -29,7 +29,7 @@ define void @fill_with_zeros3(ptr %dst) { ; CHECK-LABEL: @fill_with_zeros3( -; CHECK-NEXT: store i32 1684234849, ptr [[DST:%.*]], align 1 +; CHECK-NEXT: store <4 x i8> , ptr [[DST:%.*]], align 1 ; CHECK-NEXT: ret void ; tail call ptr @strncpy(ptr %dst, ptr @str3, i64 4) Index: llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll =================================================================== --- llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll +++ llvm/test/Transforms/InstCombine/struct-assign-tbaa-new.ll @@ -13,8 +13,8 @@ define void @test1(ptr %a1, ptr %a2) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[A2:%.*]], align 4, !tbaa [[TBAA0:![0-9]+]] -; CHECK-NEXT: store i32 [[TMP0]], ptr [[A1:%.*]], align 4, !tbaa [[TBAA0]] +; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i8>, ptr [[A2:%.*]], align 4, !tbaa [[TBAA0:![0-9]+]] +; CHECK-NEXT: store <4 x i8> [[TMP0]], ptr [[A1:%.*]], align 4, !tbaa [[TBAA0]] ; CHECK-NEXT: ret void ; entry: @@ -27,7 +27,7 @@ define ptr @test2() { ; CHECK-LABEL: @test2( ; CHECK-NEXT: [[TMP:%.*]] = alloca [[B:%.*]], align 8 -; CHECK-NEXT: store i64 poison, ptr null, align 4294967296 +; CHECK-NEXT: store <8 x i8> poison, ptr null, align 4294967296 ; CHECK-NEXT: ret ptr [[TMP]] ; %tmp = alloca %B, align 8 Index: llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll =================================================================== --- llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll +++ llvm/test/Transforms/InstCombine/struct-assign-tbaa.ll @@ -13,8 +13,8 @@ define void @test1(ptr nocapture %a, ptr nocapture %b) { ; CHECK-LABEL: @test1( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[B:%.*]], align 4, !tbaa [[TBAA0:![0-9]+]] -; CHECK-NEXT: store i32 [[TMP0]], ptr [[A:%.*]], align 4, !tbaa [[TBAA0]] +; CHECK-NEXT: [[TMP0:%.*]] = load <4 x i8>, ptr [[B:%.*]], align 4, !tbaa [[TBAA0:![0-9]+]] +; CHECK-NEXT: store <4 x i8> [[TMP0]], ptr [[A:%.*]], align 4, !tbaa [[TBAA0]] ; CHECK-NEXT: ret void ; entry: @@ -27,7 +27,7 @@ define ptr @test2() { ; CHECK-LABEL: @test2( ; CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_TEST2:%.*]], align 8 -; CHECK-NEXT: store i64 poison, ptr null, align 4294967296 +; CHECK-NEXT: store <8 x i8> poison, ptr null, align 4294967296 ; CHECK-NEXT: ret ptr [[TMP]] ; %tmp = alloca %struct.test2, align 8 Index: llvm/test/Transforms/PhaseOrdering/X86/SROA-after-final-loop-unrolling-2.ll =================================================================== --- llvm/test/Transforms/PhaseOrdering/X86/SROA-after-final-loop-unrolling-2.ll +++ llvm/test/Transforms/PhaseOrdering/X86/SROA-after-final-loop-unrolling-2.ll @@ -27,30 +27,43 @@ ; CHECK-NEXT: [[ARG_OFF:%.*]] = add i32 [[ARG]], 127 ; CHECK-NEXT: [[TMP0:%.*]] = icmp ult i32 [[ARG_OFF]], 255 ; CHECK-NEXT: br i1 [[TMP0]], label [[BB12:%.*]], label [[BB13:%.*]] -; CHECK: bb12.loopexit: -; CHECK-NEXT: [[I3_SROA_8_0_INSERT_EXT:%.*]] = zext i32 [[I21_3:%.*]] to i64 -; CHECK-NEXT: [[I3_SROA_8_0_INSERT_SHIFT:%.*]] = shl nuw i64 [[I3_SROA_8_0_INSERT_EXT]], 32 -; CHECK-NEXT: [[I3_SROA_0_0_INSERT_EXT:%.*]] = zext i32 [[I21_2:%.*]] to i64 -; CHECK-NEXT: [[I3_SROA_0_0_INSERT_INSERT:%.*]] = or i64 [[I3_SROA_8_0_INSERT_SHIFT]], [[I3_SROA_0_0_INSERT_EXT]] -; CHECK-NEXT: br label [[BB12]] ; CHECK: bb12: -; CHECK-NEXT: [[TMP1:%.*]] = phi i64 [ [[I3_SROA_0_0_INSERT_INSERT]], [[BB12_LOOPEXIT:%.*]] ], [ 180388626456, [[BB:%.*]] ] -; CHECK-NEXT: store i64 [[TMP1]], ptr [[ARG1:%.*]], align 4, !tbaa [[TBAA5:![0-9]+]] +; CHECK-NEXT: [[TMP1:%.*]] = phi <8 x i8> [ , [[BB:%.*]] ], [ [[I3_SROA_0_4_VECBLEND24:%.*]], [[BB13]] ] +; CHECK-NEXT: store <8 x i8> [[TMP1]], ptr [[ARG1:%.*]], align 4, !tbaa [[TBAA5:![0-9]+]] ; CHECK-NEXT: ret void ; CHECK: bb13: -; CHECK-NEXT: [[I3_SROA_8_0:%.*]] = phi i32 [ [[I21_3]], [[BB13]] ], [ 42, [[BB]] ] -; CHECK-NEXT: [[I3_SROA_0_0:%.*]] = phi i32 [ [[I21_2]], [[BB13]] ], [ 24, [[BB]] ] +; CHECK-NEXT: [[I3_SROA_0_0:%.*]] = phi <8 x i8> [ [[I3_SROA_0_4_VECBLEND24]], [[BB13]] ], [ , [[BB]] ] ; CHECK-NEXT: [[I4_05:%.*]] = phi i32 [ [[I24_3:%.*]], [[BB13]] ], [ 0, [[BB]] ] -; CHECK-NEXT: [[I21:%.*]] = mul nsw i32 [[I3_SROA_0_0]], [[I4_05]] +; CHECK-NEXT: [[I3_SROA_0_0_VEC_EXTRACT_BC:%.*]] = bitcast <8 x i8> [[I3_SROA_0_0]] to <2 x i32> +; CHECK-NEXT: [[I3_SROA_0_0_VEC_EXTRACT_EXTRACT:%.*]] = extractelement <2 x i32> [[I3_SROA_0_0_VEC_EXTRACT_BC]], i64 0 +; CHECK-NEXT: [[I21:%.*]] = mul nsw i32 [[I3_SROA_0_0_VEC_EXTRACT_EXTRACT]], [[I4_05]] +; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32 [[I21]] to <4 x i8> +; CHECK-NEXT: [[I3_SROA_0_0_VEC_EXPAND:%.*]] = shufflevector <4 x i8> [[TMP2]], <4 x i8> poison, <8 x i32> +; CHECK-NEXT: [[I3_SROA_0_0_VECBLEND:%.*]] = shufflevector <8 x i8> [[I3_SROA_0_0_VEC_EXPAND]], <8 x i8> [[I3_SROA_0_0]], <8 x i32> ; CHECK-NEXT: [[I24:%.*]] = or i32 [[I4_05]], 1 -; CHECK-NEXT: [[I21_1:%.*]] = mul nsw i32 [[I3_SROA_8_0]], [[I24]] +; CHECK-NEXT: [[I3_SROA_0_4_VEC_EXTRACT_BC:%.*]] = bitcast <8 x i8> [[I3_SROA_0_0_VECBLEND]] to <2 x i32> +; CHECK-NEXT: [[I3_SROA_0_4_VEC_EXTRACT_EXTRACT:%.*]] = extractelement <2 x i32> [[I3_SROA_0_4_VEC_EXTRACT_BC]], i64 1 +; CHECK-NEXT: [[I21_1:%.*]] = mul nsw i32 [[I3_SROA_0_4_VEC_EXTRACT_EXTRACT]], [[I24]] +; CHECK-NEXT: [[TMP3:%.*]] = bitcast i32 [[I21_1]] to <4 x i8> +; CHECK-NEXT: [[I3_SROA_0_4_VEC_EXPAND:%.*]] = shufflevector <4 x i8> [[TMP3]], <4 x i8> poison, <8 x i32> +; CHECK-NEXT: [[I3_SROA_0_4_VECBLEND:%.*]] = shufflevector <8 x i8> [[I3_SROA_0_0_VECBLEND]], <8 x i8> [[I3_SROA_0_4_VEC_EXPAND]], <8 x i32> ; CHECK-NEXT: [[I24_1:%.*]] = or i32 [[I4_05]], 2 -; CHECK-NEXT: [[I21_2]] = mul nsw i32 [[I21]], [[I24_1]] +; CHECK-NEXT: [[I3_SROA_0_0_VEC_EXTRACT18_BC:%.*]] = bitcast <8 x i8> [[I3_SROA_0_4_VECBLEND]] to <2 x i32> +; CHECK-NEXT: [[I3_SROA_0_0_VEC_EXTRACT18_EXTRACT:%.*]] = extractelement <2 x i32> [[I3_SROA_0_0_VEC_EXTRACT18_BC]], i64 0 +; CHECK-NEXT: [[I21_2:%.*]] = mul nsw i32 [[I3_SROA_0_0_VEC_EXTRACT18_EXTRACT]], [[I24_1]] +; CHECK-NEXT: [[TMP4:%.*]] = bitcast i32 [[I21_2]] to <4 x i8> +; CHECK-NEXT: [[I3_SROA_0_0_VEC_EXPAND15:%.*]] = shufflevector <4 x i8> [[TMP4]], <4 x i8> poison, <8 x i32> +; CHECK-NEXT: [[I3_SROA_0_0_VECBLEND16:%.*]] = shufflevector <8 x i8> [[I3_SROA_0_0_VEC_EXPAND15]], <8 x i8> [[I3_SROA_0_4_VECBLEND]], <8 x i32> ; CHECK-NEXT: [[I24_2:%.*]] = or i32 [[I4_05]], 3 -; CHECK-NEXT: [[I21_3]] = mul nsw i32 [[I21_1]], [[I24_2]] +; CHECK-NEXT: [[I3_SROA_0_4_VEC_EXTRACT21_BC:%.*]] = bitcast <8 x i8> [[I3_SROA_0_0_VECBLEND16]] to <2 x i32> +; CHECK-NEXT: [[I3_SROA_0_4_VEC_EXTRACT21_EXTRACT:%.*]] = extractelement <2 x i32> [[I3_SROA_0_4_VEC_EXTRACT21_BC]], i64 1 +; CHECK-NEXT: [[I21_3:%.*]] = mul nsw i32 [[I3_SROA_0_4_VEC_EXTRACT21_EXTRACT]], [[I24_2]] +; CHECK-NEXT: [[TMP5:%.*]] = bitcast i32 [[I21_3]] to <4 x i8> +; CHECK-NEXT: [[I3_SROA_0_4_VEC_EXPAND23:%.*]] = shufflevector <4 x i8> [[TMP5]], <4 x i8> poison, <8 x i32> +; CHECK-NEXT: [[I3_SROA_0_4_VECBLEND24]] = shufflevector <8 x i8> [[I3_SROA_0_0_VECBLEND16]], <8 x i8> [[I3_SROA_0_4_VEC_EXPAND23]], <8 x i32> ; CHECK-NEXT: [[I24_3]] = add nuw nsw i32 [[I4_05]], 4 ; CHECK-NEXT: [[I11_NOT_3:%.*]] = icmp eq i32 [[I24_3]], [[I10]] -; CHECK-NEXT: br i1 [[I11_NOT_3]], label [[BB12_LOOPEXIT]], label [[BB13]], !llvm.loop [[LOOP8:![0-9]+]] +; CHECK-NEXT: br i1 [[I11_NOT_3]], label [[BB12]], label [[BB13]], !llvm.loop [[LOOP8:![0-9]+]] ; bb: %i = alloca i32, align 4