Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -4508,10 +4508,9 @@ EmitAlignmentAssumption(Ret.getScalarVal(), AlignmentCI->getZExtValue(), OffsetValue); } else if (const auto *AA = TargetDecl->getAttr()) { - llvm::Value *ParamVal = - CallArgs[AA->getParamIndex().getLLVMIndex()].getRValue( - *this).getScalarVal(); - EmitAlignmentAssumption(Ret.getScalarVal(), ParamVal); + CallArg Arg = CallArgs[AA->getParamIndex().getLLVMIndex()]; + llvm::Value *ParamVal = Arg.getRValue(*this).getScalarVal(); + EmitAlignmentAssumption(Ret.getScalarVal(), ParamVal, *Arg.getType()); } } Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2803,9 +2803,16 @@ void unprotectFromPeepholes(PeepholeProtection protection); void EmitAlignmentAssumption(llvm::Value *PtrValue, llvm::Value *Alignment, + const clang::Type &AlignmentType, llvm::Value *OffsetValue = nullptr) { - Builder.CreateAlignmentAssumption(CGM.getDataLayout(), PtrValue, Alignment, - OffsetValue); + assert(AlignmentType.isIntegralOrUnscopedEnumerationType() && + "Alignment can only be an integer type"); + Builder.CreateAlignmentAssumption( + CGM.getDataLayout(), PtrValue, Alignment, + AlignmentType.isSignedIntegerOrEnumerationType() + ? llvm::AlignmentSign::Signed + : llvm::AlignmentSign::Unsigned, + OffsetValue); } //===--------------------------------------------------------------------===// Index: test/CodeGen/alloc-align-attr.c =================================================================== --- test/CodeGen/alloc-align-attr.c +++ test/CodeGen/alloc-align-attr.c @@ -8,9 +8,12 @@ return *m1(a); // CHECK: call i32* @m1(i32 [[PARAM1:%[^\)]+]]) // CHECK: [[ALIGNCAST1:%.+]] = sext i32 [[PARAM1]] to i64 -// CHECK: [[ISPOS1:%.+]] = icmp sgt i64 [[ALIGNCAST1]], 0 -// CHECK: [[POSMASK1:%.+]] = sub i64 [[ALIGNCAST1]], 1 -// CHECK: [[MASK1:%.+]] = select i1 [[ISPOS1]], i64 [[POSMASK1]], i64 0 +// CHECK: [[ISPOS:%.+]] = icmp sgt i64 [[ALIGNCAST1]], 0 +// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[ALIGNCAST1]], 1 +// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[ALIGNCAST1]], [[ALIGNSUB1]] +// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0 +// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]] +// CHECK: [[MASK1:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0 // CHECK: [[PTRINT1:%.+]] = ptrtoint // CHECK: [[MASKEDPTR1:%.+]] = and i64 [[PTRINT1]], [[MASK1]] // CHECK: [[MASKCOND1:%.+]] = icmp eq i64 [[MASKEDPTR1]], 0 @@ -23,9 +26,12 @@ // CHECK: [[CONV2:%.+]] = trunc i64 %{{.+}} to i32 // CHECK: call i32* @m1(i32 [[CONV2]]) // CHECK: [[ALIGNCAST2:%.+]] = sext i32 [[CONV2]] to i64 -// CHECK: [[ISPOS2:%.+]] = icmp sgt i64 [[ALIGNCAST2]], 0 -// CHECK: [[POSMASK2:%.+]] = sub i64 [[ALIGNCAST2]], 1 -// CHECK: [[MASK2:%.+]] = select i1 [[ISPOS2]], i64 [[POSMASK2]], i64 0 +// CHECK: [[ISPOS:%.+]] = icmp sgt i64 [[ALIGNCAST2]], 0 +// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[ALIGNCAST2]], 1 +// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[ALIGNCAST2]], [[ALIGNSUB1]] +// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0 +// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]] +// CHECK: [[MASK2:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0 // CHECK: [[PTRINT2:%.+]] = ptrtoint // CHECK: [[MASKEDPTR2:%.+]] = and i64 [[PTRINT2]], [[MASK2]] // CHECK: [[MASKCOND2:%.+]] = icmp eq i64 [[MASKEDPTR2]], 0 @@ -39,9 +45,12 @@ return *m2(a); // CHECK: [[CONV3:%.+]] = sext i32 %{{.+}} to i64 // CHECK: call i32* @m2(i64 [[CONV3]]) -// CHECK: [[ISPOS3:%.+]] = icmp sgt i64 [[CONV3]], 0 -// CHECK: [[POSMASK3:%.+]] = sub i64 [[CONV3]], 1 -// CHECK: [[MASK3:%.+]] = select i1 [[ISPOS3]], i64 [[POSMASK3]], i64 0 +// CHECK: [[ISPOS:%.+]] = icmp ugt i64 [[CONV3]], 0 +// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[CONV3]], 1 +// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[CONV3]], [[ALIGNSUB1]] +// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0 +// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]] +// CHECK: [[MASK3:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0 // CHECK: [[PTRINT3:%.+]] = ptrtoint // CHECK: [[MASKEDPTR3:%.+]] = and i64 [[PTRINT3]], [[MASK3]] // CHECK: [[MASKCOND3:%.+]] = icmp eq i64 [[MASKEDPTR3]], 0 @@ -53,16 +62,18 @@ // CHECK: define i32 @test4 return *m2(a); // CHECK: call i32* @m2(i64 [[PARAM4:%[^\)]+]]) -// CHECK: [[ISPOS4:%.+]] = icmp sgt i64 [[PARAM4]], 0 -// CHECK: [[POSMASK4:%.+]] = sub i64 [[PARAM4]], 1 -// CHECK: [[MASK4:%.+]] = select i1 [[ISPOS4]], i64 [[POSMASK4]], i64 0 +// CHECK: [[ISPOS:%.+]] = icmp ugt i64 [[PARAM4]], 0 +// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[PARAM4]], 1 +// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[PARAM4]], [[ALIGNSUB1]] +// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0 +// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]] +// CHECK: [[MASK4:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0 // CHECK: [[PTRINT4:%.+]] = ptrtoint // CHECK: [[MASKEDPTR4:%.+]] = and i64 [[PTRINT4]], [[MASK4]] // CHECK: [[MASKCOND4:%.+]] = icmp eq i64 [[MASKEDPTR4]], 0 // CHECK: call void @llvm.assume(i1 [[MASKCOND4]]) } - struct Empty {}; struct MultiArgs { __INT64_TYPE__ a, b;}; // Struct parameter doesn't take up an IR parameter, 'i' takes up 2. @@ -74,9 +85,12 @@ return *m3(e, a); // CHECK: call i32* @m3(i64 %{{.*}}, i64 %{{.*}}) // CHECK: [[ALIGNCAST5:%.+]] = trunc i128 %{{.*}} to i64 -// CHECK: [[ISPOS5:%.+]] = icmp sgt i64 [[ALIGNCAST5]], 0 -// CHECK: [[POSMASK5:%.+]] = sub i64 [[ALIGNCAST5]], 1 -// CHECK: [[MASK5:%.+]] = select i1 [[ISPOS5]], i64 [[POSMASK5]], i64 0 +// CHECK: [[ISPOS:%.+]] = icmp sgt i64 [[ALIGNCAST5]], 0 +// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[ALIGNCAST5]], 1 +// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[ALIGNCAST5]], [[ALIGNSUB1]] +// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0 +// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]] +// CHECK: [[MASK5:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0 // CHECK: [[PTRINT5:%.+]] = ptrtoint // CHECK: [[MASKEDPTR5:%.+]] = and i64 [[PTRINT5]], [[MASK5]] // CHECK: [[MASKCOND5:%.+]] = icmp eq i64 [[MASKEDPTR5]], 0 @@ -90,9 +104,12 @@ return *m4(e, a); // CHECK: call i32* @m4(i64 %{{.*}}, i64 %{{.*}}, i64 %{{.*}}) // CHECK: [[ALIGNCAST6:%.+]] = trunc i128 %{{.*}} to i64 -// CHECK: [[ISPOS6:%.+]] = icmp sgt i64 [[ALIGNCAST6]], 0 -// CHECK: [[POSMASK6:%.+]] = sub i64 [[ALIGNCAST6]], 1 -// CHECK: [[MASK6:%.+]] = select i1 [[ISPOS6]], i64 [[POSMASK6]], i64 0 +// CHECK: [[ISPOS:%.+]] = icmp sgt i64 [[ALIGNCAST6]], 0 +// CHECK: [[ALIGNSUB1:%.+]] = sub i64 [[ALIGNCAST6]], 1 +// CHECK: [[ALIGNANDSUB1:%.+]] = and i64 [[ALIGNCAST6]], [[ALIGNSUB1]] +// CHECK: [[ISPOWER2:%.+]] = icmp eq i64 [[ALIGNANDSUB1]], 0 +// CHECK: [[ALIGNVALID:%.+]] = and i1 [[ISPOS]], [[ISPOWER2]] +// CHECK: [[MASK6:%.+]] = select i1 [[ALIGNVALID]], i64 [[ALIGNSUB1]], i64 0 // CHECK: [[PTRINT6:%.+]] = ptrtoint // CHECK: [[MASKEDPTR6:%.+]] = and i64 [[PTRINT6]], [[MASK6]] // CHECK: [[MASKCOND6:%.+]] = icmp eq i64 [[MASKEDPTR6]], 0