Index: llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp =================================================================== --- llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp +++ llvm/lib/Transforms/Utils/SimplifyLibCalls.cpp @@ -152,7 +152,9 @@ } static void annotateNonNullNoUndefBasedOnAccess(CallInst *CI, - ArrayRef ArgNos) { + ArrayRef ArgNos, + const DataLayout &DL, + Value *Size = nullptr) { Function *F = CI->getCaller(); if (!F) return; @@ -168,23 +170,24 @@ continue; CI->addParamAttr(ArgNo, Attribute::NonNull); - annotateDereferenceableBytes(CI, ArgNo, 1); + if (!Size || (Size && isKnownNonZero(Size, DL))) + annotateDereferenceableBytes(CI, ArgNo, 1); } } -static void annotateNonNullAndDereferenceable(CallInst *CI, ArrayRef ArgNos, - Value *Size, const DataLayout &DL) { +static void annotateNonNullAndDereferenceable(CallInst *CI, + ArrayRef ArgNos, + Value *Size, + const DataLayout &DL) { + annotateNonNullNoUndefBasedOnAccess(CI, ArgNos, DL, Size); if (ConstantInt *LenC = dyn_cast(Size)) { - annotateNonNullNoUndefBasedOnAccess(CI, ArgNos); annotateDereferenceableBytes(CI, ArgNos, LenC->getZExtValue()); } else if (isKnownNonZero(Size, DL)) { - annotateNonNullNoUndefBasedOnAccess(CI, ArgNos); const APInt *X, *Y; - uint64_t DerefMin = 1; - if (match(Size, m_Select(m_Value(), m_APInt(X), m_APInt(Y)))) { - DerefMin = std::min(X->getZExtValue(), Y->getZExtValue()); - annotateDereferenceableBytes(CI, ArgNos, DerefMin); - } + uint64_t MinDereferenceableBytes = 1; + if (match(Size, m_Select(m_Value(), m_APInt(X), m_APInt(Y)))) + MinDereferenceableBytes = std::min(X->getZExtValue(), Y->getZExtValue()); + annotateDereferenceableBytes(CI, ArgNos, MinDereferenceableBytes); } } @@ -209,7 +212,7 @@ // Extract some information from the instruction Value *Dst = CI->getArgOperand(0); Value *Src = CI->getArgOperand(1); - annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}); + annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}, DL); // See if we can get the length of the input string. uint64_t Len = GetStringLength(Src); @@ -253,9 +256,8 @@ Value *Src = CI->getArgOperand(1); Value *Size = CI->getArgOperand(2); uint64_t Len; - annotateNonNullNoUndefBasedOnAccess(CI, 0); - if (isKnownNonZero(Size, DL)) - annotateNonNullNoUndefBasedOnAccess(CI, 1); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL); + annotateNonNullNoUndefBasedOnAccess(CI, 1, DL, Size); // We don't do anything if length is not constant. ConstantInt *LengthArg = dyn_cast(Size); @@ -294,7 +296,7 @@ Function *Callee = CI->getCalledFunction(); FunctionType *FT = Callee->getFunctionType(); Value *SrcStr = CI->getArgOperand(0); - annotateNonNullNoUndefBasedOnAccess(CI, 0); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL); // If the second operand is non-constant, see if we can compute the length // of the input string and turn this into memchr. @@ -340,7 +342,7 @@ Value *LibCallSimplifier::optimizeStrRChr(CallInst *CI, IRBuilderBase &B) { Value *SrcStr = CI->getArgOperand(0); ConstantInt *CharC = dyn_cast(CI->getArgOperand(1)); - annotateNonNullNoUndefBasedOnAccess(CI, 0); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL); // Cannot fold anything if we're not looking for a constant. if (!CharC) @@ -419,7 +421,7 @@ B, DL, TLI)); } - annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}); + annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}, DL); return nullptr; } @@ -430,8 +432,7 @@ if (Str1P == Str2P) // strncmp(x,x,n) -> 0 return ConstantInt::get(CI->getType(), 0); - if (isKnownNonZero(Size, DL)) - annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}); + annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}, DL, Size); // Get the length argument if it is constant. uint64_t Length; if (ConstantInt *LengthArg = dyn_cast(Size)) @@ -514,7 +515,7 @@ if (Dst == Src) // strcpy(x,x) -> x return Src; - annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}); + annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}, DL); // See if we can get the length of the input string. uint64_t Len = GetStringLength(Src); if (Len) @@ -572,9 +573,8 @@ Value *Dst = CI->getArgOperand(0); Value *Src = CI->getArgOperand(1); Value *Size = CI->getArgOperand(2); - annotateNonNullNoUndefBasedOnAccess(CI, 0); - if (isKnownNonZero(Size, DL)) - annotateNonNullNoUndefBasedOnAccess(CI, 1); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL); + annotateNonNullNoUndefBasedOnAccess(CI, 1, DL, Size); uint64_t Len; if (ConstantInt *LengthArg = dyn_cast(Size)) @@ -749,7 +749,7 @@ Value *LibCallSimplifier::optimizeStrLen(CallInst *CI, IRBuilderBase &B) { if (Value *V = optimizeStringLength(CI, B, 8)) return V; - annotateNonNullNoUndefBasedOnAccess(CI, 0); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL); return nullptr; } @@ -758,8 +758,7 @@ if (Value *V = optimizeStringLength(CI, B, 8, Bound)) return V; - if (isKnownNonZero(Bound, DL)) - annotateNonNullNoUndefBasedOnAccess(CI, 0); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL, Bound); return nullptr; } @@ -909,7 +908,7 @@ return StrChr ? B.CreateBitCast(StrChr, CI->getType()) : nullptr; } - annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}); + annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}, DL); return nullptr; } @@ -980,8 +979,7 @@ Value *LibCallSimplifier::optimizeMemChr(CallInst *CI, IRBuilderBase &B) { Value *SrcStr = CI->getArgOperand(0); Value *Size = CI->getArgOperand(2); - if (isKnownNonZero(Size, DL)) - annotateNonNullNoUndefBasedOnAccess(CI, 0); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL, Size); Value *CharVal = CI->getArgOperand(1); ConstantInt *CharC = dyn_cast(CharVal); @@ -2563,7 +2561,7 @@ return New; } - annotateNonNullNoUndefBasedOnAccess(CI, 0); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL); return nullptr; } @@ -2686,7 +2684,7 @@ return New; } - annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}); + annotateNonNullNoUndefBasedOnAccess(CI, {0, 1}, DL); return nullptr; } @@ -2777,8 +2775,7 @@ return V; } - if (isKnownNonZero(CI->getOperand(1), DL)) - annotateNonNullNoUndefBasedOnAccess(CI, 0); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL, CI->getOperand(1)); return nullptr; } @@ -2924,7 +2921,7 @@ } Value *LibCallSimplifier::optimizePuts(CallInst *CI, IRBuilderBase &B) { - annotateNonNullNoUndefBasedOnAccess(CI, 0); + annotateNonNullNoUndefBasedOnAccess(CI, 0, DL); if (!CI->use_empty()) return nullptr; Index: llvm/test/Transforms/InstCombine/bcmp-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/bcmp-1.ll +++ llvm/test/Transforms/InstCombine/bcmp-1.ll @@ -82,8 +82,8 @@ define i1 @test_simplify7(i64 %x, i64 %y) { ; CHECK-LABEL: @test_simplify7( -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[DOTNOT]] ; %x.addr = alloca i64, align 8 %y.addr = alloca i64, align 8 @@ -100,8 +100,8 @@ define i1 @test_simplify8(i32 %x, i32 %y) { ; CHECK-LABEL: @test_simplify8( -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[DOTNOT]] ; %x.addr = alloca i32, align 4 %y.addr = alloca i32, align 4 @@ -118,8 +118,8 @@ define i1 @test_simplify9(i16 %x, i16 %y) { ; CHECK-LABEL: @test_simplify9( -; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i16 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: ret i1 [[TMP1]] +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i16 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[DOTNOT]] ; %x.addr = alloca i16, align 2 %y.addr = alloca i16, align 2 @@ -134,7 +134,7 @@ define i1 @test_simplify10(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_simplify10( -; CHECK-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* [[MEM1:%.*]], i8* [[MEM2:%.*]], i32 [[SIZE:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* noundef nonnull [[MEM1:%.*]], i8* noundef nonnull [[MEM2:%.*]], i32 [[SIZE:%.*]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; Index: llvm/test/Transforms/InstCombine/bcopy.ll =================================================================== --- llvm/test/Transforms/InstCombine/bcopy.ll +++ llvm/test/Transforms/InstCombine/bcopy.ll @@ -17,7 +17,7 @@ define void @bcopy_memmove2(i8* nocapture readonly %a, i8* nocapture %b, i32 %len) { ; CHECK-LABEL: @bcopy_memmove2( -; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* align 1 [[B:%.*]], i8* align 1 [[A:%.*]], i32 [[LEN:%.*]], i1 false) +; CHECK-NEXT: tail call void @llvm.memmove.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[B:%.*]], i8* noundef nonnull align 1 [[A:%.*]], i32 [[LEN:%.*]], i1 false) ; CHECK-NEXT: ret void ; tail call void @bcopy(i8* %a, i8* %b, i32 %len) Index: llvm/test/Transforms/InstCombine/mem-deref-bytes-addrspaces.ll =================================================================== --- llvm/test/Transforms/InstCombine/mem-deref-bytes-addrspaces.ll +++ llvm/test/Transforms/InstCombine/mem-deref-bytes-addrspaces.ll @@ -14,7 +14,7 @@ define i32 @memcmp_nonconst_size_nonnnull(i8 addrspace(1)* nocapture readonly %d, i8* nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcmp_nonconst_size_nonnnull( -; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8 addrspace(1)* nonnull dereferenceable_or_null(40) [[D:%.*]], i8* nonnull [[S:%.*]], i64 [[N:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8 addrspace(1)* noundef nonnull dereferenceable_or_null(40) [[D:%.*]], i8* noundef nonnull [[S:%.*]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i32 [[CALL]] ; %call = tail call i32 @memcmp(i8 addrspace(1)* nonnull dereferenceable_or_null(40) %d, i8* nonnull %s, i64 %n) Index: llvm/test/Transforms/InstCombine/mem-deref-bytes.ll =================================================================== --- llvm/test/Transforms/InstCombine/mem-deref-bytes.ll +++ llvm/test/Transforms/InstCombine/mem-deref-bytes.ll @@ -93,7 +93,7 @@ define i32 @memcmp_nonconst_size(i8* nocapture readonly %d, i8* nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcmp_nonconst_size( -; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* [[D:%.*]], i8* [[S:%.*]], i64 [[N:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = tail call i32 @memcmp(i8* noundef nonnull [[D:%.*]], i8* noundef nonnull [[S:%.*]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i32 [[CALL]] ; %call = tail call i32 @memcmp(i8* %d, i8* %s, i64 %n) Index: llvm/test/Transforms/InstCombine/memchr-2.ll =================================================================== --- llvm/test/Transforms/InstCombine/memchr-2.ll +++ llvm/test/Transforms/InstCombine/memchr-2.ll @@ -125,7 +125,7 @@ define i8* @call_ax_1_n(i64 %n) { ; CHECK-LABEL: @call_ax_1_n( -; CHECK-NEXT: [[RES:%.*]] = call i8* @memchr(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i32 1, i64 [[N:%.*]]) +; CHECK-NEXT: [[RES:%.*]] = call i8* @memchr(i8* noundef nonnull getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i32 1, i64 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[RES]] ; Index: llvm/test/Transforms/InstCombine/memchr.ll =================================================================== --- llvm/test/Transforms/InstCombine/memchr.ll +++ llvm/test/Transforms/InstCombine/memchr.ll @@ -205,7 +205,7 @@ define i8* @test16(i8* %str, i32 %c, i32 %n) { ; CHECK-LABEL: @test16( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef nonnull [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[RET]] ; @@ -215,7 +215,7 @@ define i8* @test17(i8* %str, i32 %c, i32 %n) { ; CHECK-LABEL: @test17( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* nonnull [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8* @memchr(i8* noundef nonnull [[STR:%.*]], i32 [[C:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[RET]] ; Index: llvm/test/Transforms/InstCombine/memcmp-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memcmp-1.ll +++ llvm/test/Transforms/InstCombine/memcmp-1.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Test that the memcmp library call simplifier works correctly. ; ; RUN: opt < %s -passes=instcombine -S | FileCheck --check-prefix=CHECK --check-prefix=NOBCMP %s @@ -35,9 +36,9 @@ define i32 @test_simplify3(i8* %mem1, i8* %mem2) { ; CHECK-LABEL: @test_simplify3( -; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* %mem1, align 1 +; CHECK-NEXT: [[LHSC:%.*]] = load i8, i8* [[MEM1:%.*]], align 1 ; CHECK-NEXT: [[LHSV:%.*]] = zext i8 [[LHSC]] to i32 -; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* %mem2, align 1 +; CHECK-NEXT: [[RHSC:%.*]] = load i8, i8* [[MEM2:%.*]], align 1 ; CHECK-NEXT: [[RHSV:%.*]] = zext i8 [[RHSC]] to i32 ; CHECK-NEXT: [[CHARDIFF:%.*]] = sub nsw i32 [[LHSV]], [[RHSV]] ; CHECK-NEXT: ret i32 [[CHARDIFF]] @@ -82,8 +83,8 @@ define i1 @test_simplify7(i64 %x, i64 %y) { ; CHECK-LABEL: @test_simplify7( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i64 %x, %y -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i64 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[DOTNOT]] ; %x.addr = alloca i64, align 8 %y.addr = alloca i64, align 8 @@ -100,8 +101,8 @@ define i1 @test_simplify8(i32 %x, i32 %y) { ; CHECK-LABEL: @test_simplify8( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 %x, %y -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[DOTNOT]] ; %x.addr = alloca i32, align 4 %y.addr = alloca i32, align 4 @@ -118,8 +119,8 @@ define i1 @test_simplify9(i16 %x, i16 %y) { ; CHECK-LABEL: @test_simplify9( -; CHECK-NEXT: [[CMP:%.*]] = icmp eq i16 %x, %y -; CHECK-NEXT: ret i1 [[CMP]] +; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i16 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: ret i1 [[DOTNOT]] ; %x.addr = alloca i16, align 2 %y.addr = alloca i16, align 2 @@ -136,13 +137,13 @@ define i1 @test_simplify10(i8* %mem1, i8* %mem2, i32 %size) { ; NOBCMP-LABEL: @test_simplify10( -; NOBCMP-NEXT: [[CALL:%.*]] = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 %size) +; NOBCMP-NEXT: [[CALL:%.*]] = call i32 @memcmp(i8* noundef nonnull [[MEM1:%.*]], i8* noundef nonnull [[MEM2:%.*]], i32 [[SIZE:%.*]]) ; NOBCMP-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 ; NOBCMP-NEXT: ret i1 [[CMP]] ; ; BCMP-LABEL: @test_simplify10( -; BCMP-NEXT: [[CALL:%.*]] = call i32 @bcmp(i8* %mem1, i8* %mem2, i32 %size) -; BCMP-NEXT: [[CMP:%.*]] = icmp eq i32 [[CALL]], 0 +; BCMP-NEXT: [[BCMP:%.*]] = call i32 @bcmp(i8* noundef nonnull [[MEM1:%.*]], i8* noundef nonnull [[MEM2:%.*]], i32 [[SIZE:%.*]]) +; BCMP-NEXT: [[CMP:%.*]] = icmp eq i32 [[BCMP]], 0 ; BCMP-NEXT: ret i1 [[CMP]] ; %call = call i32 @memcmp(i8* %mem1, i8* %mem2, i32 %size) Index: llvm/test/Transforms/InstCombine/memcpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memcpy-1.ll +++ llvm/test/Transforms/InstCombine/memcpy-1.ll @@ -11,7 +11,7 @@ define i8* @test_simplify1(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_simplify1( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[MEM1:%.*]], i8* align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[MEM1:%.*]], i8* noundef nonnull align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) ; CHECK-NEXT: ret i8* [[MEM1]] ; %ret = call i8* @memcpy(i8* %mem1, i8* %mem2, i32 %size) @@ -22,7 +22,7 @@ define i8* @test_simplify2(i8* %mem1, i8* %mem2, i32 %size) strictfp { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[MEM1:%.*]], i8* align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[MEM1:%.*]], i8* noundef nonnull align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) #[[ATTR0:[0-9]+]] ; CHECK-NEXT: ret i8* [[MEM1]] ; %ret = call i8* @memcpy(i8* %mem1, i8* %mem2, i32 %size) strictfp @@ -36,7 +36,7 @@ define i8* @test_simplify3(i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_simplify3( ; CHECK-NEXT: [[DEST:%.*]] = call i8* @get_dest() -; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DEST]], i8* align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[DEST]], i8* noundef nonnull align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) ; CHECK-NEXT: ret i8* [[DEST]] ; @@ -47,7 +47,7 @@ define i8* @test_no_incompatible_attr(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_no_incompatible_attr( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[MEM1:%.*]], i8* align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[MEM1:%.*]], i8* noundef nonnull align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) ; CHECK-NEXT: ret i8* [[MEM1]] ; Index: llvm/test/Transforms/InstCombine/memcpy-2.ll =================================================================== --- llvm/test/Transforms/InstCombine/memcpy-2.ll +++ llvm/test/Transforms/InstCombine/memcpy-2.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Test that the memcpy library call simplifier works correctly. ; ; RUN: opt < %s -passes=instcombine -S | FileCheck %s @@ -10,7 +11,7 @@ define i8 @test_no_simplify1(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: [[RET:%.*]] = call i8 @memcpy(i8* %mem1, i8* %mem2, i32 %size) +; CHECK-NEXT: [[RET:%.*]] = call i8 @memcpy(i8* [[MEM1:%.*]], i8* [[MEM2:%.*]], i32 [[SIZE:%.*]]) ; CHECK-NEXT: ret i8 [[RET]] ; %ret = call i8 @memcpy(i8* %mem1, i8* %mem2, i32 %size) Index: llvm/test/Transforms/InstCombine/memmove-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memmove-1.ll +++ llvm/test/Transforms/InstCombine/memmove-1.ll @@ -1,3 +1,4 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; Test that the memmove library call simplifier works correctly. ; ; RUN: opt < %s -passes=instcombine -S | FileCheck %s @@ -10,32 +11,36 @@ define i8* @test_simplify1(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_simplify1( +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[MEM1:%.*]], i8* noundef nonnull align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: ret i8* [[MEM1]] +; %ret = call i8* @memmove(i8* %mem1, i8* %mem2, i32 %size) -; CHECK: call void @llvm.memmove ret i8* %ret -; CHECK: ret i8* %mem1 } define i8* @test_simplify2(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_simplify2( -; CHECK-NEXT: tail call void @llvm.memmove -; CHECK-NEXT: ret i8* %mem1 +; CHECK-NEXT: tail call void @llvm.memmove.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[MEM1:%.*]], i8* noundef nonnull align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: ret i8* [[MEM1]] +; %ret = tail call i8* @memmove(i8* %mem1, i8* %mem2, i32 %size) ret i8* %ret } define i8* @test_no_simplify1(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_no_simplify1( -; CHECK-NEXT: %ret = musttail call i8* @memmove(i8* %mem1, i8* %mem2, i32 %size) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @memmove(i8* [[MEM1:%.*]], i8* [[MEM2:%.*]], i32 [[SIZE:%.*]]) +; CHECK-NEXT: ret i8* [[RET]] +; %ret = musttail call i8* @memmove(i8* %mem1, i8* %mem2, i32 %size) ret i8* %ret } define i8* @test_no_incompatible_attr(i8* %mem1, i8* %mem2, i32 %size) { ; CHECK-LABEL: @test_no_incompatible_attr( +; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[MEM1:%.*]], i8* noundef nonnull align 1 [[MEM2:%.*]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: ret i8* [[MEM1]] +; %ret = call dereferenceable(1) i8* @memmove(i8* %mem1, i8* %mem2, i32 %size) -; CHECK: call void @llvm.memmove ret i8* %ret -; CHECK: ret i8* %mem1 } Index: llvm/test/Transforms/InstCombine/memmove.ll =================================================================== --- llvm/test/Transforms/InstCombine/memmove.ll +++ llvm/test/Transforms/InstCombine/memmove.ll @@ -19,7 +19,7 @@ define void @test2(i8* %A, i32 %N) { ;; dest can't alias source since we can't write to source! ; CHECK-LABEL: @test2( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[A:%.*]], i8* align 16 getelementptr inbounds ([33 x i8], [33 x i8]* @S, i64 0, i64 0), i32 [[N:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[A:%.*]], i8* noundef nonnull align 16 getelementptr inbounds ([33 x i8], [33 x i8]* @S, i64 0, i64 0), i32 [[N:%.*]], i1 false) ; CHECK-NEXT: ret void ; call void @llvm.memmove.p0i8.p0i8.i32(i8* %A, i8* getelementptr inbounds ([33 x i8], [33 x i8]* @S, i32 0, i32 0), i32 %N, i1 false) Index: llvm/test/Transforms/InstCombine/mempcpy.ll =================================================================== --- llvm/test/Transforms/InstCombine/mempcpy.ll +++ llvm/test/Transforms/InstCombine/mempcpy.ll @@ -3,7 +3,7 @@ define i8* @memcpy_nonconst_n(i8* %d, i8* nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcpy_nonconst_n( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[D:%.*]], i8* align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 [[D:%.*]], i8* noundef nonnull align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[D]], i64 [[N]] ; CHECK-NEXT: ret i8* [[TMP1]] ; @@ -13,7 +13,7 @@ define i8* @memcpy_nonconst_n_copy_attrs(i8* %d, i8* nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcpy_nonconst_n_copy_attrs( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 dereferenceable(16) [[D:%.*]], i8* align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(16) [[D:%.*]], i8* noundef nonnull align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[D]], i64 [[N]] ; CHECK-NEXT: ret i8* [[TMP1]] ; @@ -23,7 +23,7 @@ define void @memcpy_nonconst_n_unused_retval(i8* %d, i8* nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcpy_nonconst_n_unused_retval( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 [[D:%.*]], i8* align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 [[D:%.*]], i8* noundef nonnull align 1 [[S:%.*]], i64 [[N:%.*]], i1 false) ; CHECK-NEXT: ret void ; call i8* @mempcpy(i8* %d, i8* %s, i64 %n) @@ -45,7 +45,7 @@ define i8* @memcpy_big_const_n(i8* %d, i8* nocapture readonly %s) { ; CHECK-LABEL: @memcpy_big_const_n( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(1024) [[D:%.*]], i8* noundef nonnull align 1 dereferenceable(1024) [[S:%.*]], i64 1024, i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 dereferenceable(1024) [[D:%.*]], i8* noundef nonnull align 1 dereferenceable(1024) [[S:%.*]], i64 1024, i1 false) ; CHECK-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, i8* [[D]], i64 1024 ; CHECK-NEXT: ret i8* [[TMP1]] ; @@ -57,7 +57,7 @@ define i32 @PR48810() { ; CHECK-LABEL: @PR48810( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* align 1 undef, i8* align 4294967296 null, i64 undef, i1 false) +; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* noundef nonnull align 1 undef, i8* noundef nonnull align 4294967296 null, i64 undef, i1 false) ; CHECK-NEXT: ret i32 undef ; %r = call dereferenceable(1) i8* @mempcpy(i8* undef, i8* null, i64 undef) @@ -66,8 +66,8 @@ define i8* @memcpy_no_simplify1(i8* %d, i8* nocapture readonly %s, i64 %n) { ; CHECK-LABEL: @memcpy_no_simplify1( -; CHECK-NEXT: %r = musttail call i8* @mempcpy(i8* %d, i8* %s, i64 %n) -; CHECK-NEXT: ret i8* %r +; CHECK-NEXT: [[R:%.*]] = musttail call i8* @mempcpy(i8* [[D:%.*]], i8* [[S:%.*]], i64 [[N:%.*]]) +; CHECK-NEXT: ret i8* [[R]] ; %r = musttail call i8* @mempcpy(i8* %d, i8* %s, i64 %n) ret i8* %r Index: llvm/test/Transforms/InstCombine/memrchr-3.ll =================================================================== --- llvm/test/Transforms/InstCombine/memrchr-3.ll +++ llvm/test/Transforms/InstCombine/memrchr-3.ll @@ -196,7 +196,7 @@ define i8* @fold_memrchr_a12345_3_n(i64 %n) { ; CHECK-LABEL: @fold_memrchr_a12345_3_n( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 0), i32 3, i64 [[N:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* noundef nonnull getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 0), i32 3, i64 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[RET]] ; @@ -210,7 +210,7 @@ define i8* @fold_memrchr_a12345_5_n(i64 %n) { ; CHECK-LABEL: @fold_memrchr_a12345_5_n( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 0), i32 5, i64 [[N:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* noundef nonnull getelementptr inbounds ([5 x i8], [5 x i8]* @a12345, i64 0, i64 0), i32 5, i64 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[RET]] ; @@ -302,7 +302,7 @@ define i8* @call_memrchr_a123123_3_n(i64 %n) { ; CHECK-LABEL: @call_memrchr_a123123_3_n( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @a123123, i64 0, i64 0), i32 3, i64 [[N:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* noundef nonnull getelementptr inbounds ([6 x i8], [6 x i8]* @a123123, i64 0, i64 0), i32 3, i64 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[RET]] ; @@ -316,7 +316,7 @@ define i8* @call_memrchr_a123123_2_n(i64 %n) { ; CHECK-LABEL: @call_memrchr_a123123_2_n( -; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @a123123, i64 0, i64 0), i32 2, i64 [[N:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8* @memrchr(i8* noundef nonnull getelementptr inbounds ([6 x i8], [6 x i8]* @a123123, i64 0, i64 0), i32 2, i64 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[RET]] ; Index: llvm/test/Transforms/InstCombine/memset-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memset-1.ll +++ llvm/test/Transforms/InstCombine/memset-1.ll @@ -14,7 +14,7 @@ define i8* @test_simplify1(i8* %mem, i32 %val, i32 %size) { ; CHECK-LABEL: @test_simplify1( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[VAL:%.*]] to i8 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[MEM:%.*]], i8 [[TMP1]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[MEM:%.*]], i8 [[TMP1]], i32 [[SIZE:%.*]], i1 false) ; CHECK-NEXT: ret i8* [[MEM]] ; %ret = call i8* @memset(i8* %mem, i32 %val, i32 %size) @@ -24,7 +24,7 @@ define i8* @test_simplify1_tail(i8* %mem, i32 %val, i32 %size) { ; CHECK-LABEL: @test_simplify1_tail( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[VAL:%.*]] to i8 -; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* align 1 [[MEM:%.*]], i8 [[TMP1]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[MEM:%.*]], i8 [[TMP1]], i32 [[SIZE:%.*]], i1 false) ; CHECK-NEXT: ret i8* [[MEM]] ; %ret = tail call i8* @memset(i8* %mem, i32 %val, i32 %size) @@ -33,8 +33,8 @@ define i8* @test_simplify1_musttail(i8* %mem, i32 %val, i32 %size) { ; CHECK-LABEL: @test_simplify1_musttail( -; CHECK-NEXT: %ret = musttail call i8* @memset(i8* %mem, i32 %val, i32 %size) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @memset(i8* [[MEM:%.*]], i32 [[VAL:%.*]], i32 [[SIZE:%.*]]) +; CHECK-NEXT: ret i8* [[RET]] ; %ret = musttail call i8* @memset(i8* %mem, i32 %val, i32 %size) ret i8* %ret @@ -44,8 +44,9 @@ define i8* @pr25892_lite(i32 %size) #0 { ; CHECK-LABEL: @pr25892_lite( -; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i32 [[SIZE:%.*]]) -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[CALL]], i8 0, i32 [[SIZE]], i1 false) +; CHECK-NEXT: [[CALL1:%.*]] = call i8* @malloc(i32 [[SIZE:%.*]]) #[[ATTR0:[0-9]+]] +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[CALL1]], i8 0, i32 [[SIZE]], i1 false) #[[ATTR0]] +; CHECK-NEXT: ret i8* [[CALL1]] ; %call1 = call i8* @malloc(i32 %size) #1 %call2 = call i8* @memset(i8* %call1, i32 0, i32 %size) #1 @@ -58,7 +59,7 @@ define i8* @malloc_and_memset_intrinsic(i32 %n) #0 { ; CHECK-LABEL: @malloc_and_memset_intrinsic( ; CHECK-NEXT: [[CALL:%.*]] = call i8* @malloc(i32 [[N:%.*]]) -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[CALL]], i8 0, i32 [[N]], i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[CALL]], i8 0, i32 [[N]], i1 false) ; CHECK-NEXT: ret i8* [[CALL]] ; %call = call i8* @malloc(i32 %n) @@ -71,8 +72,8 @@ define i8* @notmalloc_memset(i32 %size, i8*(i32)* %notmalloc) { ; CHECK-LABEL: @notmalloc_memset( -; CHECK-NEXT: [[CALL1:%.*]] = call i8* [[NOTMALLOC:%.*]](i32 [[SIZE:%.*]]) [[ATTR0:#.*]] -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[CALL1]], i8 0, i32 [[SIZE]], i1 false) [[ATTR0]] +; CHECK-NEXT: [[CALL1:%.*]] = call i8* [[NOTMALLOC:%.*]](i32 [[SIZE:%.*]]) #[[ATTR0]] +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[CALL1]], i8 0, i32 [[SIZE]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[CALL1]] ; %call1 = call i8* %notmalloc(i32 %size) #1 @@ -86,12 +87,12 @@ define float* @pr25892(i32 %size) #0 { ; CHECK-LABEL: @pr25892( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @malloc(i32 [[SIZE:%.*]]) [[ATTR0]] +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @malloc(i32 [[SIZE:%.*]]) #[[ATTR0]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[CALL]], null ; CHECK-NEXT: br i1 [[CMP]], label [[CLEANUP:%.*]], label [[IF_END:%.*]] ; CHECK: if.end: ; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[CALL]] to float* -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[CALL]], i8 0, i32 [[SIZE]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[CALL]], i8 0, i32 [[SIZE]], i1 false) #[[ATTR0]] ; CHECK-NEXT: br label [[CLEANUP]] ; CHECK: cleanup: ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi float* [ [[BC]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ] @@ -114,9 +115,9 @@ define i8* @buffer_is_modified_then_memset(i32 %size) { ; CHECK-LABEL: @buffer_is_modified_then_memset( -; CHECK-NEXT: [[PTR:%.*]] = tail call i8* @malloc(i32 [[SIZE:%.*]]) [[ATTR0]] +; CHECK-NEXT: [[PTR:%.*]] = tail call i8* @malloc(i32 [[SIZE:%.*]]) #[[ATTR0]] ; CHECK-NEXT: store i8 1, i8* [[PTR]], align 1 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR]], i8 0, i32 [[SIZE]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[PTR]], i8 0, i32 [[SIZE]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %ptr = tail call i8* @malloc(i32 %size) #1 @@ -128,7 +129,7 @@ define i8* @memset_size_select(i1 %b, i8* %ptr) { ; CHECK-LABEL: @memset_size_select( ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[B:%.*]], i32 10, i32 50 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(10) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(10) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %size = select i1 %b, i32 10, i32 50 @@ -140,7 +141,7 @@ define i8* @memset_size_select2(i1 %b, i8* %ptr) { ; CHECK-LABEL: @memset_size_select2( ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[B:%.*]], i32 10, i32 50 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(80) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(80) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %size = select i1 %b, i32 10, i32 50 @@ -151,7 +152,7 @@ define i8* @memset_size_select3(i1 %b, i8* %ptr) { ; CHECK-LABEL: @memset_size_select3( ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[B:%.*]], i32 10, i32 50 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) ; CHECK-NEXT: ret i8* [[PTR]] ; %size = select i1 %b, i32 10, i32 50 @@ -162,7 +163,7 @@ define i8* @memset_size_select4(i1 %b, i8* %ptr) { ; CHECK-LABEL: @memset_size_select4( ; CHECK-NEXT: [[SIZE:%.*]] = select i1 [[B:%.*]], i32 10, i32 50 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %size = select i1 %b, i32 10, i32 50 @@ -173,7 +174,7 @@ define i8* @memset_size_ashr(i1 %b, i8* %ptr, i32 %v) { ; CHECK-LABEL: @memset_size_ashr( ; CHECK-NEXT: [[SIZE:%.*]] = ashr i32 -2, [[V:%.*]] -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(1) [[PTR:%.*]], i8 0, i32 [[SIZE]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %size = ashr i32 -2, %v @@ -183,28 +184,26 @@ define i8* @memset_attrs1(i1 %b, i8* %ptr, i32 %size) { ; CHECK-LABEL: @memset_attrs1( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 dereferenceable_or_null(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable_or_null(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %memset = tail call i8* @memset(i8* dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1 ret i8* %memset } -; be sure to drop nonnull since size is unknown and can be 0 ; do not change dereferenceable attribute define i8* @memset_attrs2(i1 %b, i8* %ptr, i32 %size) { ; CHECK-LABEL: @memset_attrs2( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %memset = tail call i8* @memset(i8* nonnull dereferenceable(40) %ptr, i32 0, i32 %size) #1 ret i8* %memset } -; size is unknown, just copy attrs, no changes in attrs define i8* @memset_attrs3(i1 %b, i8* %ptr, i32 %size) { ; CHECK-LABEL: @memset_attrs3( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 dereferenceable_or_null(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 dereferenceable_or_null(40) [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %memset = tail call i8* @memset(i8* nonnull dereferenceable_or_null(40) %ptr, i32 0, i32 %size) #1 @@ -214,7 +213,7 @@ ; be sure to drop nonnull since size is unknown and can be 0 define i8* @memset_attrs4(i1 %b, i8* %ptr, i32 %size) { ; CHECK-LABEL: @memset_attrs4( -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* nonnull align 1 [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) [[ATTR0]] +; CHECK-NEXT: tail call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[PTR:%.*]], i8 0, i32 [[SIZE:%.*]], i1 false) #[[ATTR0]] ; CHECK-NEXT: ret i8* [[PTR]] ; %memset = tail call i8* @memset(i8* nonnull %ptr, i32 0, i32 %size) #1 @@ -224,7 +223,7 @@ define i8* @test_no_incompatible_attr(i8* %mem, i32 %val, i32 %size) { ; CHECK-LABEL: @test_no_incompatible_attr( ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[VAL:%.*]] to i8 -; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[MEM:%.*]], i8 [[TMP1]], i32 [[SIZE:%.*]], i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[MEM:%.*]], i8 [[TMP1]], i32 [[SIZE:%.*]], i1 false) ; CHECK-NEXT: ret i8* [[MEM]] ; %ret = call dereferenceable(1) i8* @memset(i8* %mem, i32 %val, i32 %size) Index: llvm/test/Transforms/InstCombine/memset_chk-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/memset_chk-1.ll +++ llvm/test/Transforms/InstCombine/memset_chk-1.ll @@ -83,8 +83,8 @@ define i8* @test_no_simplify3(i8* %dst, i32 %a, i64 %b, i64 %c) { ; CHECK-LABEL: @test_no_simplify3( -; CHECK-NEXT: %ret = musttail call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @__memset_chk(i8* [[DST:%.*]], i32 0, i64 1824, i64 1824) +; CHECK-NEXT: ret i8* [[RET]] ; %ret = musttail call i8* @__memset_chk(i8* %dst, i32 0, i64 1824, i64 1824) ret i8* %ret @@ -106,7 +106,7 @@ ; CHECK-NEXT: [[SUB183:%.*]] = ptrtoint i8* [[B]] to i64 ; CHECK-NEXT: [[SUB184:%.*]] = sub i64 [[SUB182]], [[SUB183]] ; CHECK-NEXT: [[ADD52_I_I:%.*]] = add nsw i64 [[SUB184]], 1 -; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* align 1 [[STRCHR1]], i8 0, i64 [[ADD52_I_I]], i1 false) +; CHECK-NEXT: call void @llvm.memset.p0i8.i64(i8* noundef nonnull align 1 [[STRCHR1]], i8 0, i64 [[ADD52_I_I]], i1 false) ; CHECK-NEXT: ret i32 4 ; entry: @@ -136,13 +136,13 @@ define float* @pr25892(i64 %size) #0 { ; CHECK-LABEL: @pr25892( ; CHECK-NEXT: entry: -; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @malloc(i64 [[SIZE:%.*]]) [[ATTR3:#.*]] +; CHECK-NEXT: [[CALL:%.*]] = tail call i8* @malloc(i64 [[SIZE:%.*]]) #[[ATTR3:[0-9]+]] ; CHECK-NEXT: [[CMP:%.*]] = icmp eq i8* [[CALL]], null ; CHECK-NEXT: br i1 [[CMP]], label [[CLEANUP:%.*]], label [[IF_END:%.*]] ; CHECK: if.end: ; CHECK-NEXT: [[BC:%.*]] = bitcast i8* [[CALL]] to float* ; CHECK-NEXT: [[CALL2:%.*]] = tail call i64 @llvm.objectsize.i64.p0i8(i8* nonnull [[CALL]], i1 false, i1 false, i1 false) -; CHECK-NEXT: [[CALL3:%.*]] = tail call i8* @__memset_chk(i8* nonnull [[CALL]], i32 0, i64 [[SIZE]], i64 [[CALL2]]) [[ATTR3]] +; CHECK-NEXT: [[CALL3:%.*]] = tail call i8* @__memset_chk(i8* nonnull [[CALL]], i32 0, i64 [[SIZE]], i64 [[CALL2]]) #[[ATTR3]] ; CHECK-NEXT: br label [[CLEANUP]] ; CHECK: cleanup: ; CHECK-NEXT: [[RETVAL_0:%.*]] = phi float* [ [[BC]], [[IF_END]] ], [ null, [[ENTRY:%.*]] ] Index: llvm/test/Transforms/InstCombine/snprintf.ll =================================================================== --- llvm/test/Transforms/InstCombine/snprintf.ll +++ llvm/test/Transforms/InstCombine/snprintf.ll @@ -19,10 +19,10 @@ ret void } -; size is '0', do not add nonnull attribute +; size is '0', do not add dereferenceable attribute define void @test_not_const_fmt_zero_size_return_value(i8* %buf, i8* %fmt) #0 { ; CHECK-LABEL: @test_not_const_fmt_zero_size_return_value( -; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 0, i8* [[FMT:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* noundef nonnull [[BUF:%.*]], i64 0, i8* [[FMT:%.*]]) ; CHECK-NEXT: ret void ; %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 0, i8* %fmt) #2 @@ -31,7 +31,7 @@ define void @test_not_const_size(i8* %buf, i64 %size) #0 { ; CHECK-LABEL: @test_not_const_size( -; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 [[SIZE:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) +; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* noundef nonnull [[BUF:%.*]], i64 [[SIZE:%.*]], i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) ; CHECK-NEXT: ret void ; %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 %size, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0)) #2 @@ -66,7 +66,7 @@ define i32 @test_percentage_return_value() #0 { ; CHECK-LABEL: @test_percentage_return_value( -; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* null, i64 0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0)) +; CHECK-NEXT: [[CALL:%.*]] = call i32 (i8*, i64, i8*, ...) @snprintf(i8* noundef nonnull null, i64 0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0)) ; CHECK-NEXT: ret i32 [[CALL]] ; %call = call i32 (i8*, i64, i8*, ...) @snprintf(i8* null, i64 0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.1, i64 0, i64 0)) #3 @@ -142,7 +142,7 @@ ; snprintf(buf, 32, "") -> memcpy -> store define i32 @test_str_ok_size_tail(i8* %buf) { ; CHECK-LABEL: @test_str_ok_size_tail( -; CHECK-NEXT: store i8 0, i8* %buf, align 1 +; CHECK-NEXT: store i8 0, i8* [[BUF:%.*]], align 1 ; CHECK-NEXT: ret i32 0 ; %1 = tail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0)) @@ -151,8 +151,8 @@ define i32 @test_str_ok_size_musttail(i8* %buf, i64 %x, i8* %y, ...) { ; CHECK-LABEL: @test_str_ok_size_musttail( -; CHECK-NEXT: %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0), ...) -; CHECK-NEXT: ret i32 %1 +; CHECK-NEXT: [[TMP1:%.*]] = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0), ...) +; CHECK-NEXT: ret i32 [[TMP1]] ; %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([1 x i8], [1 x i8]* @.str.4, i64 0, i64 0), ...) ret i32 %1 @@ -171,8 +171,8 @@ define i32 @test_str_ok_size_musttail2(i8* %buf, i64 %x, i8* %y, ...) { ; CHECK-LABEL: @test_str_ok_size_musttail2( -; CHECK-NEXT: %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), ...) -; CHECK-NEXT: ret i32 %1 +; CHECK-NEXT: [[TMP1:%.*]] = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* [[BUF:%.*]], i64 8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), ...) +; CHECK-NEXT: ret i32 [[TMP1]] ; %1 = musttail call i32 (i8*, i64, i8*, ...) @snprintf(i8* %buf, i64 8, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.3, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), ...) ret i32 %1 Index: llvm/test/Transforms/InstCombine/sprintf-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/sprintf-1.ll +++ llvm/test/Transforms/InstCombine/sprintf-1.ll @@ -109,7 +109,7 @@ ; NOSTPCPY-LABEL: @test_simplify7( ; NOSTPCPY-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) [[STR:%.*]]) ; NOSTPCPY-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1 -; NOSTPCPY-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false) +; NOSTPCPY-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[DST:%.*]], i8* noundef nonnull align 1 [[STR]], i32 [[LENINC]], i1 false) ; NOSTPCPY-NEXT: ret i32 [[STRLEN]] ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0 @@ -142,7 +142,7 @@ ; WIN-LABEL: @test_simplify9( ; WIN-NEXT: [[STRLEN:%.*]] = call i32 @strlen(i8* noundef nonnull dereferenceable(1) [[STR:%.*]]) ; WIN-NEXT: [[LENINC:%.*]] = add i32 [[STRLEN]], 1 -; WIN-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 [[DST:%.*]], i8* align 1 [[STR]], i32 [[LENINC]], i1 false) +; WIN-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 [[DST:%.*]], i8* noundef nonnull align 1 [[STR]], i32 [[LENINC]], i1 false) ; WIN-NEXT: ret i32 [[STRLEN]] ; %fmt = getelementptr [3 x i8], [3 x i8]* @percent_s, i32 0, i32 0 Index: llvm/test/Transforms/InstCombine/strcmp-memcmp.ll =================================================================== --- llvm/test/Transforms/InstCombine/strcmp-memcmp.ll +++ llvm/test/Transforms/InstCombine/strcmp-memcmp.ll @@ -504,7 +504,7 @@ define i32 @strncmp_memcmp_bad2([12 x i8]* dereferenceable (12) %buf, i64 %n) nofree nosync { ; CHECK-LABEL: @strncmp_memcmp_bad2( ; CHECK-NEXT: [[STRING:%.*]] = getelementptr inbounds [12 x i8], [12 x i8]* [[BUF:%.*]], i64 0, i64 0 -; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* nonnull [[STRING]], i64 [[N:%.*]]) +; CHECK-NEXT: [[CALL:%.*]] = call i32 @strncmp(i8* noundef nonnull getelementptr inbounds ([4 x i8], [4 x i8]* @key, i64 0, i64 0), i8* noundef nonnull [[STRING]], i64 [[N:%.*]]) ; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[CALL]], 1 ; CHECK-NEXT: [[CONV:%.*]] = zext i1 [[CMP]] to i32 ; CHECK-NEXT: ret i32 [[CONV]] Index: llvm/test/Transforms/InstCombine/strcpy_chk-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strcpy_chk-1.ll +++ llvm/test/Transforms/InstCombine/strcpy_chk-1.ll @@ -26,7 +26,7 @@ define i8* @test_simplify1_tail() { ; CHECK-LABEL: @test_simplify1_tail( -; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) +; CHECK-NEXT: tail call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0), i8* noundef nonnull align 1 dereferenceable(12) getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i32 12, i1 false) ; CHECK-NEXT: ret i8* getelementptr inbounds ([60 x i8], [60 x i8]* @a, i32 0, i32 0) ; %dst = getelementptr inbounds [60 x i8], [60 x i8]* @a, i32 0, i32 0 @@ -147,8 +147,8 @@ define i8* @test_no_simplify2(i8* %dst, i8* %src, i32 %a) { ; CHECK-LABEL: @test_no_simplify2( -; CHECK-NEXT: %ret = musttail call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @__strcpy_chk(i8* [[DST:%.*]], i8* [[SRC:%.*]], i32 60) +; CHECK-NEXT: ret i8* [[RET]] ; %ret = musttail call i8* @__strcpy_chk(i8* %dst, i8* %src, i32 60) ret i8* %ret Index: llvm/test/Transforms/InstCombine/strncat-2.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncat-2.ll +++ llvm/test/Transforms/InstCombine/strncat-2.ll @@ -58,10 +58,10 @@ ret void } -; strncat(nonnull x, nonnull y, n) -> strncat(nonnull x, y, n) +; strncat(nonnull x, nonnull y, n) -> strncat(nonnull noundef x, nonnull noundef y, n) define i8* @test1(i8* %str1, i8* %str2, i32 %n) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* noundef nonnull [[STR1:%.*]], i8* nonnull [[STR2:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* noundef nonnull [[STR1:%.*]], i8* noundef nonnull [[STR2:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[TEMP1]] ; @@ -92,7 +92,7 @@ define i8* @test4(i8* %str1, i8* %str2, i32 %n) null_pointer_is_valid { ; CHECK-LABEL: @test4( -; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* noundef [[STR1:%.*]], i8* [[STR2:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[TEMP1:%.*]] = call i8* @strncat(i8* noundef [[STR1:%.*]], i8* noundef [[STR2:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[TEMP1]] ; Index: llvm/test/Transforms/InstCombine/strncmp-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncmp-1.ll +++ llvm/test/Transforms/InstCombine/strncmp-1.ll @@ -107,10 +107,10 @@ ret i32 %temp1 } -; strncmp(nonnull x, nonnull y, n) -> strncmp(x, y, n) +; strncmp(nonnull x, nonnull y, n) -> strncmp(nonnull noundef x, nonnull noundef y, n) define i32 @test9(i8* %str1, i8* %str2, i32 %n) { ; CHECK-LABEL: @test9( -; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @strncmp(i8* nonnull [[STR1:%.*]], i8* nonnull [[STR2:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @strncmp(i8* noundef nonnull [[STR1:%.*]], i8* noundef nonnull [[STR2:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i32 [[TEMP1]] ; @@ -141,7 +141,7 @@ define i32 @test12(i8* %str1, i8* %str2, i32 %n) null_pointer_is_valid { ; CHECK-LABEL: @test12( -; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @strncmp(i8* [[STR1:%.*]], i8* [[STR2:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[TEMP1:%.*]] = call i32 @strncmp(i8* noundef [[STR1:%.*]], i8* noundef [[STR2:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i32 [[TEMP1]] ; Index: llvm/test/Transforms/InstCombine/strncpy-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strncpy-1.ll +++ llvm/test/Transforms/InstCombine/strncpy-1.ll @@ -107,7 +107,7 @@ define void @test_simplify7(i8* %dst, i32 %n) { ; CHECK-LABEL: @test_simplify7( -; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncpy(i8* noundef nonnull dereferenceable(80) [[DST:%.*]], i8* getelementptr inbounds ([1 x i8], [1 x i8]* @null, i32 0, i32 0), i32 [[N:%.*]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8* @strncpy(i8* noundef nonnull dereferenceable(80) [[DST:%.*]], i8* noundef nonnull getelementptr inbounds ([1 x i8], [1 x i8]* @null, i32 0, i32 0), i32 [[N:%.*]]) ; CHECK-NEXT: ret void ; %src = getelementptr [1 x i8], [1 x i8]* @null, i32 0, i32 0 @@ -117,7 +117,7 @@ define i8* @test1(i8* %dst, i8* %src, i32 %n) { ; CHECK-LABEL: @test1( -; CHECK-NEXT: [[RET:%.*]] = call i8* @strncpy(i8* noundef nonnull [[DST:%.*]], i8* nonnull [[SRC:%.*]], i32 [[N:%.*]]) +; CHECK-NEXT: [[RET:%.*]] = call i8* @strncpy(i8* noundef nonnull [[DST:%.*]], i8* noundef nonnull [[SRC:%.*]], i32 [[N:%.*]]) ; CHECK-NEXT: ret i8* [[RET]] ; %ret = call i8* @strncpy(i8* nonnull %dst, i8* nonnull %src, i32 %n) @@ -182,8 +182,8 @@ define i8* @test_no_simplify3(i8* %dst, i8* %src, i32 %count) { ; CHECK-LABEL: @test_no_simplify3( -; CHECK-NEXT: %ret = musttail call i8* @strncpy(i8* %dst, i8* %src, i32 32) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @strncpy(i8* [[DST:%.*]], i8* [[SRC:%.*]], i32 32) +; CHECK-NEXT: ret i8* [[RET]] ; %ret = musttail call i8* @strncpy(i8* %dst, i8* %src, i32 32) ret i8* %ret @@ -191,8 +191,8 @@ define i8* @test_no_simplify4(i8* %dst, i8* %src, i32 %count) { ; CHECK-LABEL: @test_no_simplify4( -; CHECK-NEXT: %ret = musttail call i8* @strncpy(i8* %dst, i8* %src, i32 6) -; CHECK-NEXT: ret i8* %ret +; CHECK-NEXT: [[RET:%.*]] = musttail call i8* @strncpy(i8* [[DST:%.*]], i8* [[SRC:%.*]], i32 6) +; CHECK-NEXT: ret i8* [[RET]] ; %ret = musttail call i8* @strncpy(i8* %dst, i8* %src, i32 6) ret i8* %ret Index: llvm/test/Transforms/InstCombine/strnlen-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strnlen-1.ll +++ llvm/test/Transforms/InstCombine/strnlen-1.ll @@ -11,12 +11,12 @@ @s5_3 = constant [9 x i8] c"12345\00xyz" -; Verify that the strnlen pointer argument is not annotated nonnull when +; Verify that the strnlen pointer argument is not annotated dereferenceable when ; nothing is known about the bound. define i64 @no_access_strnlen_p_n(i8* %ptr, i64 %n) { ; CHECK-LABEL: @no_access_strnlen_p_n( -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR:%.*]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR:%.*]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; %len = call i64 @strnlen(i8* %ptr, i64 %n) @@ -69,9 +69,9 @@ define i64 @fold_strnlen_ax_1() { ; CHECK-LABEL: @fold_strnlen_ax_1( ; CHECK-NEXT: [[STRNLEN_CHAR0:%.*]] = load i8, i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), align 1 -; CHECK-NEXT: [[STRNLEN_CHAR0CMP_NOT:%.*]] = icmp ne i8 [[STRNLEN_CHAR0]], 0 -; CHECK-NEXT: [[STRNLEN_SEL:%.*]] = zext i1 [[STRNLEN_CHAR0CMP_NOT]] to i64 -; CHECK-NEXT: ret i64 [[STRNLEN_SEL]] +; CHECK-NEXT: [[STRNLEN_CHAR0CMP:%.*]] = icmp ne i8 [[STRNLEN_CHAR0]], 0 +; CHECK-NEXT: [[TMP1:%.*]] = zext i1 [[STRNLEN_CHAR0CMP]] to i64 +; CHECK-NEXT: ret i64 [[TMP1]] ; %ptr = getelementptr [0 x i8], [0 x i8]* @ax, i32 0, i32 0 %len = call i64 @strnlen(i8* %ptr, i64 1) Index: llvm/test/Transforms/InstCombine/strnlen-3.ll =================================================================== --- llvm/test/Transforms/InstCombine/strnlen-3.ll +++ llvm/test/Transforms/InstCombine/strnlen-3.ll @@ -32,7 +32,7 @@ define i64 @call_strnlen_sx_pi_n(i64 %i, i64 %n) { ; CHECK-LABEL: @call_strnlen_sx_pi_n( ; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [0 x i8], [0 x i8]* @sx, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; @@ -113,7 +113,7 @@ define i64 @call_strnlen_s5_3_pi_n(i64 zeroext %i, i64 %n) { ; CHECK-LABEL: @call_strnlen_s5_3_pi_n( ; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; %ptr = getelementptr inbounds [10 x i8], [10 x i8]* @s5_3, i32 0, i64 %i @@ -200,7 +200,7 @@ define i64 @fold_strnlen_s3_pi_n(i64 %i, i64 %n) { ; CHECK-LABEL: @fold_strnlen_s3_pi_n( ; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; Index: llvm/test/Transforms/InstCombine/strnlen-4.ll =================================================================== --- llvm/test/Transforms/InstCombine/strnlen-4.ll +++ llvm/test/Transforms/InstCombine/strnlen-4.ll @@ -19,7 +19,7 @@ ; CHECK-LABEL: @fold_strnlen_s3_pi_s5_n( ; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8* [[PTR]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[SEL]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[SEL]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; @@ -39,7 +39,7 @@ ; CHECK-LABEL: @call_strnlen_s3_pi_xbounds_s5_n( ; CHECK-NEXT: [[PTR:%.*]] = getelementptr [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8* [[PTR]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[SEL]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[SEL]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; @@ -59,7 +59,7 @@ ; CHECK-LABEL: @call_strnlen_s3_pi_sx_n( ; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [4 x i8], [4 x i8]* @s3, i64 0, i64 [[I:%.*]] ; CHECK-NEXT: [[SEL:%.*]] = select i1 [[C:%.*]], i8* [[PTR]], i8* getelementptr inbounds ([0 x i8], [0 x i8]* @sx, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[SEL]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[SEL]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; @@ -75,7 +75,7 @@ define i64 @fold_strnlen_s3_s5_pi_n(i1 %C, i64 %i, i64 %n) { ; CHECK-LABEL: @fold_strnlen_s3_s5_pi_n( ; CHECK-NEXT: [[PTR:%.*]] = select i1 [[C:%.*]], i8* getelementptr inbounds ([6 x i8], [6 x i8]* @s5, i64 0, i64 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @s3, i64 0, i64 0) -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 [[I:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 [[I:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; Index: llvm/test/Transforms/InstCombine/strnlen-5.ll =================================================================== --- llvm/test/Transforms/InstCombine/strnlen-5.ll +++ llvm/test/Transforms/InstCombine/strnlen-5.ll @@ -123,7 +123,7 @@ define i1 @call_strnlen_ax_n_eqz(i64 %n) { ; CHECK-LABEL: @call_strnlen_ax_n_eqz( -; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = tail call i64 @strnlen(i8* noundef nonnull getelementptr inbounds ([0 x i8], [0 x i8]* @ax, i64 0, i64 0), i64 [[N:%.*]]) ; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0 ; CHECK-NEXT: ret i1 [[EQZ]] ; @@ -211,7 +211,7 @@ define i1 @call_strnlen_s5_pi_n_eqz(i64 %i, i64 %n) { ; CHECK-LABEL: @call_strnlen_s5_pi_n_eqz( ; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [6 x i8], [6 x i8]* @s5, i64 0, i64 [[I:%.*]] -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* nonnull [[PTR]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 [[N:%.*]]) ; CHECK-NEXT: [[EQZ:%.*]] = icmp eq i64 [[LEN]], 0 ; CHECK-NEXT: ret i1 [[EQZ]] ; Index: llvm/test/Transforms/InstCombine/strnlen-6.ll =================================================================== --- llvm/test/Transforms/InstCombine/strnlen-6.ll +++ llvm/test/Transforms/InstCombine/strnlen-6.ll @@ -51,7 +51,7 @@ define i64 @noderef_strnlen_ecp_n(i64 %n) { ; CHECK-LABEL: @noderef_strnlen_ecp_n( ; CHECK-NEXT: [[PTR:%.*]] = load i8*, i8** @ecp, align 8 -; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* [[PTR]], i64 [[N:%.*]]) +; CHECK-NEXT: [[LEN:%.*]] = call i64 @strnlen(i8* noundef nonnull [[PTR]], i64 [[N:%.*]]) ; CHECK-NEXT: ret i64 [[LEN]] ; %ptr = load i8*, i8** @ecp Index: llvm/test/Transforms/InstCombine/strstr-1.ll =================================================================== --- llvm/test/Transforms/InstCombine/strstr-1.ll +++ llvm/test/Transforms/InstCombine/strstr-1.ll @@ -62,7 +62,7 @@ define i1 @test_simplify5(i8* %str, i8* %pat) { ; CHECK-LABEL: @test_simplify5( ; CHECK-NEXT: [[STRLEN:%.*]] = call i64 @strlen(i8* noundef nonnull dereferenceable(1) [[PAT:%.*]]) -; CHECK-NEXT: [[STRNCMP:%.*]] = call i32 @strncmp(i8* [[STR:%.*]], i8* [[PAT]], i64 [[STRLEN]]) +; CHECK-NEXT: [[STRNCMP:%.*]] = call i32 @strncmp(i8* noundef nonnull [[STR:%.*]], i8* noundef nonnull [[PAT]], i64 [[STRLEN]]) ; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[STRNCMP]], 0 ; CHECK-NEXT: ret i1 [[CMP1]] ; Index: llvm/test/Transforms/PhaseOrdering/ARM/arm_fill_q7.ll =================================================================== --- llvm/test/Transforms/PhaseOrdering/ARM/arm_fill_q7.ll +++ llvm/test/Transforms/PhaseOrdering/ARM/arm_fill_q7.ll @@ -12,20 +12,20 @@ define dso_local void @arm_fill_q7(i8 signext %value, i8* %pDst, i32 %blockSize) #0 { ; OLDPM-LABEL: @arm_fill_q7( ; OLDPM-NEXT: entry: -; OLDPM-NEXT: [[CMP_NOT20:%.*]] = icmp ult i32 [[BLOCKSIZE:%.*]], 4 -; OLDPM-NEXT: br i1 [[CMP_NOT20]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] +; OLDPM-NEXT: [[CMP_NOT17:%.*]] = icmp ult i32 [[BLOCKSIZE:%.*]], 4 +; OLDPM-NEXT: br i1 [[CMP_NOT17]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] ; OLDPM: while.body.preheader: -; OLDPM-NEXT: [[TMP0:%.*]] = and i32 [[BLOCKSIZE]], -4 -; OLDPM-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[PDST:%.*]], i8 [[VALUE:%.*]], i32 [[TMP0]], i1 false) -; OLDPM-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PDST]], i32 [[TMP0]] +; OLDPM-NEXT: [[SHR:%.*]] = and i32 [[BLOCKSIZE]], -4 +; OLDPM-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[PDST:%.*]], i8 [[VALUE:%.*]], i32 [[SHR]], i1 false), !tbaa [[TBAA3:![0-9]+]] +; OLDPM-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PDST]], i32 [[SHR]] ; OLDPM-NEXT: br label [[WHILE_END]] ; OLDPM: while.end: ; OLDPM-NEXT: [[PDST_ADDR_0_LCSSA:%.*]] = phi i8* [ [[PDST]], [[ENTRY:%.*]] ], [ [[SCEVGEP]], [[WHILE_BODY_PREHEADER]] ] ; OLDPM-NEXT: [[REM:%.*]] = and i32 [[BLOCKSIZE]], 3 -; OLDPM-NEXT: [[CMP14_NOT17:%.*]] = icmp eq i32 [[REM]], 0 -; OLDPM-NEXT: br i1 [[CMP14_NOT17]], label [[WHILE_END18:%.*]], label [[WHILE_BODY16_PREHEADER:%.*]] +; OLDPM-NEXT: [[CMP14_NOT20:%.*]] = icmp eq i32 [[REM]], 0 +; OLDPM-NEXT: br i1 [[CMP14_NOT20]], label [[WHILE_END18:%.*]], label [[WHILE_BODY16_PREHEADER:%.*]] ; OLDPM: while.body16.preheader: -; OLDPM-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[PDST_ADDR_0_LCSSA]], i8 [[VALUE]], i32 [[REM]], i1 false) +; OLDPM-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[PDST_ADDR_0_LCSSA]], i8 [[VALUE]], i32 [[REM]], i1 false), !tbaa [[TBAA3]] ; OLDPM-NEXT: br label [[WHILE_END18]] ; OLDPM: while.end18: ; OLDPM-NEXT: ret void @@ -35,9 +35,9 @@ ; NEWPM-NEXT: [[CMP_NOT17:%.*]] = icmp ult i32 [[BLOCKSIZE:%.*]], 4 ; NEWPM-NEXT: br i1 [[CMP_NOT17]], label [[WHILE_END:%.*]], label [[WHILE_BODY_PREHEADER:%.*]] ; NEWPM: while.body.preheader: -; NEWPM-NEXT: [[TMP0:%.*]] = and i32 [[BLOCKSIZE]], -4 -; NEWPM-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[PDST:%.*]], i8 [[VALUE:%.*]], i32 [[TMP0]], i1 false) -; NEWPM-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PDST]], i32 [[TMP0]] +; NEWPM-NEXT: [[SHR:%.*]] = and i32 [[BLOCKSIZE]], -4 +; NEWPM-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[PDST:%.*]], i8 [[VALUE:%.*]], i32 [[SHR]], i1 false), !tbaa [[TBAA3:![0-9]+]] +; NEWPM-NEXT: [[SCEVGEP:%.*]] = getelementptr i8, i8* [[PDST]], i32 [[SHR]] ; NEWPM-NEXT: br label [[WHILE_END]] ; NEWPM: while.end: ; NEWPM-NEXT: [[PDST_ADDR_0_LCSSA:%.*]] = phi i8* [ [[PDST]], [[ENTRY:%.*]] ], [ [[SCEVGEP]], [[WHILE_BODY_PREHEADER]] ] @@ -45,7 +45,7 @@ ; NEWPM-NEXT: [[CMP14_NOT20:%.*]] = icmp eq i32 [[REM]], 0 ; NEWPM-NEXT: br i1 [[CMP14_NOT20]], label [[WHILE_END18:%.*]], label [[WHILE_BODY16_PREHEADER:%.*]] ; NEWPM: while.body16.preheader: -; NEWPM-NEXT: call void @llvm.memset.p0i8.i32(i8* align 1 [[PDST_ADDR_0_LCSSA]], i8 [[VALUE]], i32 [[REM]], i1 false) +; NEWPM-NEXT: call void @llvm.memset.p0i8.i32(i8* noundef nonnull align 1 [[PDST_ADDR_0_LCSSA]], i8 [[VALUE]], i32 [[REM]], i1 false), !tbaa [[TBAA3]] ; NEWPM-NEXT: br label [[WHILE_END18]] ; NEWPM: while.end18: ; NEWPM-NEXT: ret void