https://github.com/hazzlim created https://github.com/llvm/llvm-project/pull/103088
Generate nuw GEPs for array subscript expressions where the base address points to the base of a constant size array and the index is unsigned. >From 1eca1fe3d73c9832bde3e09a93f8d0a2a2bb3698 Mon Sep 17 00:00:00 2001 From: Hari Limaye <hari.lim...@arm.com> Date: Thu, 13 Jun 2024 21:06:50 +0000 Subject: [PATCH] [clang] Emit nuw GEPs for array subscript expressions Generate nuw GEPs for array subscript expressions where the base address points to the base of a constant size array and the index is unsigned. --- clang/lib/CodeGen/CGBuilder.h | 6 ++- clang/lib/CodeGen/CGExpr.cpp | 41 ++++++++++++------- clang/lib/CodeGen/CGExprScalar.cpp | 38 ++++++++++------- clang/lib/CodeGen/CodeGenFunction.h | 9 ++-- clang/test/CodeGen/PowerPC/ppc-emmintrin.c | 12 +++--- clang/test/CodeGen/PowerPC/ppc-xmmintrin.c | 16 ++++---- .../CodeGenCXX/pr45964-decomp-transform.cpp | 2 +- 7 files changed, 75 insertions(+), 49 deletions(-) diff --git a/clang/lib/CodeGen/CGBuilder.h b/clang/lib/CodeGen/CGBuilder.h index 08730a6a6672a1..b8036cf6e6a306 100644 --- a/clang/lib/CodeGen/CGBuilder.h +++ b/clang/lib/CodeGen/CGBuilder.h @@ -14,6 +14,7 @@ #include "CodeGenTypeCache.h" #include "llvm/Analysis/Utils/Local.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/GEPNoWrapFlags.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Type.h" @@ -334,9 +335,10 @@ class CGBuilderTy : public CGBuilderBaseTy { Address CreateGEP(Address Addr, ArrayRef<llvm::Value *> IdxList, llvm::Type *ElementType, CharUnits Align, - const Twine &Name = "") { + const Twine &Name = "", + llvm::GEPNoWrapFlags NW = llvm::GEPNoWrapFlags::none()) { llvm::Value *Ptr = emitRawPointerFromAddress(Addr); - return RawAddress(CreateGEP(Addr.getElementType(), Ptr, IdxList, Name), + return RawAddress(CreateGEP(Addr.getElementType(), Ptr, IdxList, Name, NW), ElementType, Align); } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index f93f8dda0bd29a..74fa7594baeb9e 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -3959,13 +3959,13 @@ static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF, static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, ArrayRef<llvm::Value *> indices, llvm::Type *elementType, bool inbounds, - bool signedIndices, SourceLocation loc, - CharUnits align, + bool nuw, bool signedIndices, + SourceLocation loc, CharUnits align, const llvm::Twine &name = "arrayidx") { if (inbounds) { return CGF.EmitCheckedInBoundsGEP(addr, indices, elementType, signedIndices, CodeGenFunction::NotSubtraction, loc, - align, name); + align, name, nuw); } else { return CGF.Builder.CreateGEP(addr, indices, elementType, align, name); } @@ -4060,7 +4060,7 @@ static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase) { static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, ArrayRef<llvm::Value *> indices, - QualType eltType, bool inbounds, + QualType eltType, bool inbounds, bool nuw, bool signedIndices, SourceLocation loc, QualType *arrayType = nullptr, const Expr *Base = nullptr, @@ -4091,7 +4091,7 @@ static Address emitArraySubscriptGEP(CodeGenFunction &CGF, Address addr, if (!LastIndex || (!CGF.IsInPreservedAIRegion && !IsPreserveAIArrayBase(CGF, Base))) { addr = emitArraySubscriptGEP(CGF, addr, indices, - CGF.ConvertTypeForMem(eltType), inbounds, + CGF.ConvertTypeForMem(eltType), inbounds, nuw, signedIndices, loc, eltAlign, name); return addr; } else { @@ -4214,7 +4214,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, QualType EltType = LV.getType()->castAs<VectorType>()->getElementType(); Addr = emitArraySubscriptGEP(*this, Addr, Idx, EltType, /*inbounds*/ true, - SignedIndices, E->getExprLoc()); + /*nuw=*/false, SignedIndices, E->getExprLoc()); return MakeAddrLValue(Addr, EltType, LV.getBaseInfo(), CGM.getTBAAInfoForSubobject(LV, EltType)); } @@ -4245,7 +4245,7 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, Addr = emitArraySubscriptGEP(*this, Addr, Idx, vla->getElementType(), !getLangOpts().isSignedOverflowDefined(), - SignedIndices, E->getExprLoc()); + /*nuw=*/false, SignedIndices, E->getExprLoc()); } else if (const ObjCObjectType *OIT = E->getType()->getAs<ObjCObjectType>()){ // Indexing over an interface, as in "NSString *P; P[4];" @@ -4332,10 +4332,20 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, // Propagate the alignment from the array itself to the result. QualType arrayType = Array->getType(); - Addr = emitArraySubscriptGEP( - *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx}, - E->getType(), !getLangOpts().isSignedOverflowDefined(), SignedIndices, - E->getExprLoc(), &arrayType, E->getBase()); + + bool Inbounds = !getLangOpts().isSignedOverflowDefined(); + // (ISO/IEC 9899:TC3, 6.5.6.8) / (C++ expr.add 4.2) + // If A in A[i] is the base of a constant size array, then the addition of + // the index to the base pointer cannot wrap in an unsigned sense without + // violating the inbounds constraint. + bool NUW = !SignedIndices && Inbounds && + (getLangOpts().C99 || getLangOpts().CPlusPlus) && + getContext().getAsConstantArrayType(arrayType); + + Addr = emitArraySubscriptGEP(*this, ArrayLV.getAddress(), + {CGM.getSize(CharUnits::Zero()), Idx}, + E->getType(), Inbounds, NUW, SignedIndices, + E->getExprLoc(), &arrayType, E->getBase()); EltBaseInfo = ArrayLV.getBaseInfo(); EltTBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, E->getType()); } else { @@ -4345,8 +4355,8 @@ LValue CodeGenFunction::EmitArraySubscriptExpr(const ArraySubscriptExpr *E, QualType ptrType = E->getBase()->getType(); Addr = emitArraySubscriptGEP(*this, Addr, Idx, E->getType(), !getLangOpts().isSignedOverflowDefined(), - SignedIndices, E->getExprLoc(), &ptrType, - E->getBase()); + /*nuw=*/false, SignedIndices, E->getExprLoc(), + &ptrType, E->getBase()); } LValue LV = MakeAddrLValue(Addr, E->getType(), EltBaseInfo, EltTBAAInfo); @@ -4543,6 +4553,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, Idx = Builder.CreateNSWMul(Idx, NumElements); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, VLA->getElementType(), !getLangOpts().isSignedOverflowDefined(), + /*nuw=*/false, /*signedIndices=*/false, E->getExprLoc()); } else if (const Expr *Array = isSimpleArrayDecayOperand(E->getBase())) { // If this is A[i] where A is an array, the frontend will have decayed the @@ -4563,6 +4574,7 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, EltPtr = emitArraySubscriptGEP( *this, ArrayLV.getAddress(), {CGM.getSize(CharUnits::Zero()), Idx}, ResultExprTy, !getLangOpts().isSignedOverflowDefined(), + /*nuw=*/false, /*signedIndices=*/false, E->getExprLoc()); BaseInfo = ArrayLV.getBaseInfo(); TBAAInfo = CGM.getTBAAInfoForSubobject(ArrayLV, ResultExprTy); @@ -4572,7 +4584,8 @@ LValue CodeGenFunction::EmitArraySectionExpr(const ArraySectionExpr *E, ResultExprTy, IsLowerBound); EltPtr = emitArraySubscriptGEP(*this, Base, Idx, ResultExprTy, !getLangOpts().isSignedOverflowDefined(), - /*signedIndices=*/false, E->getExprLoc()); + /*signedIndices=*/false, /*nuw=*/false, + E->getExprLoc()); } return MakeAddrLValue(EltPtr, ResultExprTy, BaseInfo, TBAAInfo); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 84392745ea6144..c9014cb68b06eb 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -35,6 +35,7 @@ #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/FixedPointBuilder.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GEPNoWrapFlags.h" #include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/Intrinsics.h" @@ -5713,13 +5714,18 @@ static GEPOffsetAndOverflow EmitGEPOffsetInBytes(Value *BasePtr, Value *GEPVal, return {TotalOffset, OffsetOverflows}; } -Value * -CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, - ArrayRef<Value *> IdxList, - bool SignedIndices, bool IsSubtraction, - SourceLocation Loc, const Twine &Name) { +Value *CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, + ArrayRef<Value *> IdxList, + bool SignedIndices, + bool IsSubtraction, + SourceLocation Loc, + const Twine &Name, bool NUW) { llvm::Type *PtrTy = Ptr->getType(); - Value *GEPVal = Builder.CreateInBoundsGEP(ElemTy, Ptr, IdxList, Name); + + llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds(); + if (NUW) + NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap(); + Value *GEPVal = Builder.CreateGEP(ElemTy, Ptr, IdxList, Name, NWFlags); // If the pointer overflow sanitizer isn't enabled, do nothing. if (!SanOpts.has(SanitizerKind::PointerOverflow)) @@ -5833,12 +5839,16 @@ CodeGenFunction::EmitCheckedInBoundsGEP(llvm::Type *ElemTy, Value *Ptr, Address CodeGenFunction::EmitCheckedInBoundsGEP( Address Addr, ArrayRef<Value *> IdxList, llvm::Type *elementType, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, CharUnits Align, - const Twine &Name) { - if (!SanOpts.has(SanitizerKind::PointerOverflow)) - return Builder.CreateInBoundsGEP(Addr, IdxList, elementType, Align, Name); - - return RawAddress( - EmitCheckedInBoundsGEP(Addr.getElementType(), Addr.emitRawPointer(*this), - IdxList, SignedIndices, IsSubtraction, Loc, Name), - elementType, Align); + const Twine &Name, bool NUW) { + if (!SanOpts.has(SanitizerKind::PointerOverflow)) { + llvm::GEPNoWrapFlags NWFlags = llvm::GEPNoWrapFlags::inBounds(); + if (NUW) + NWFlags |= llvm::GEPNoWrapFlags::noUnsignedWrap(); + return Builder.CreateGEP(Addr, IdxList, elementType, Align, Name, NWFlags); + } + + return RawAddress(EmitCheckedInBoundsGEP( + Addr.getElementType(), Addr.emitRawPointer(*this), + IdxList, SignedIndices, IsSubtraction, Loc, Name, NUW), + elementType, Align); } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 19a7feeb69d820..f5aa8606e06323 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -5057,17 +5057,18 @@ class CodeGenFunction : public CodeGenTypeCache { /// \p SignedIndices indicates whether any of the GEP indices are signed. /// \p IsSubtraction indicates whether the expression used to form the GEP /// is a subtraction. + /// \p NUW indicates whether the GEP is nuw. llvm::Value *EmitCheckedInBoundsGEP(llvm::Type *ElemTy, llvm::Value *Ptr, ArrayRef<llvm::Value *> IdxList, - bool SignedIndices, - bool IsSubtraction, + bool SignedIndices, bool IsSubtraction, SourceLocation Loc, - const Twine &Name = ""); + const Twine &Name = "", bool NUW = false); Address EmitCheckedInBoundsGEP(Address Addr, ArrayRef<llvm::Value *> IdxList, llvm::Type *elementType, bool SignedIndices, bool IsSubtraction, SourceLocation Loc, - CharUnits Align, const Twine &Name = ""); + CharUnits Align, const Twine &Name = "", + bool NUW = false); /// Specifies which type of sanitizer check to apply when handling a /// particular builtin. diff --git a/clang/test/CodeGen/PowerPC/ppc-emmintrin.c b/clang/test/CodeGen/PowerPC/ppc-emmintrin.c index a3650beec625f2..4c4d0dfce05eaf 100644 --- a/clang/test/CodeGen/PowerPC/ppc-emmintrin.c +++ b/clang/test/CodeGen/PowerPC/ppc-emmintrin.c @@ -1012,14 +1012,14 @@ test_shuffle() { // CHECK: %[[SHR:[0-9a-zA-Z_.]+]] = ashr i32 %{{[0-9a-zA-Z_.]+}}, 6 // CHECK: %[[AND4:[0-9a-zA-Z_.]+]] = and i32 %[[SHR]], 3 // CHECK: sext i32 %[[AND4]] to i64 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %{{[0-9a-zA-Z_.]+}}, i32 0 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %{{[0-9a-zA-Z_.]+}}, i32 1 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK: %[[ADD:[0-9a-zA-Z_.]+]] = add i32 %{{[0-9a-zA-Z_.]+}}, 269488144 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %[[ADD]], i32 2 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_epi32.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK: add i32 %{{[0-9a-zA-Z_.]+}}, 269488144 // CHECK: call <4 x i32> @vec_perm(int vector[4], int vector[4], unsigned char vector[16]) @@ -1050,7 +1050,7 @@ test_shuffle() { // CHECK: sext i32 %[[AND4]] to i64 // CHECK-LE: store <2 x i64> <i64 1663540288323457296, i64 0>, ptr %{{[0-9a-zA-Z_.]+}}, align 16 // CHECK-BE: store <2 x i64> <i64 1157726452361532951, i64 0>, ptr %{{[0-9a-zA-Z_.]+}}, align 16 -// CHECK-COUNT-4: getelementptr inbounds [4 x i16], ptr @_mm_shufflehi_epi16.__permute_selectors, i64 0, i64 {{[0-9a-zA-Z_%.]+}} +// CHECK-COUNT-4: getelementptr inbounds nuw [4 x i16], ptr @_mm_shufflehi_epi16.__permute_selectors, i64 0, i64 {{[0-9a-zA-Z_%.]+}} // CHECK: call <2 x i64> @vec_perm(unsigned long long vector[2], unsigned long long vector[2], unsigned char vector[16]) // CHECK-LABEL: define available_externally <2 x i64> @_mm_shufflelo_epi16 @@ -1067,7 +1067,7 @@ test_shuffle() { // CHECK: sext i32 %[[AND4]] to i64 // CHECK-LE: store <2 x i64> <i64 0, i64 2242261671028070680>, ptr %{{[0-9a-zA-Z_.]+}}, align 16 // CHECK-BE: store <2 x i64> <i64 0, i64 1736447835066146335>, ptr %{{[0-9a-zA-Z_.]+}}, align 16 -// CHECK-COUNT-4: getelementptr inbounds [4 x i16], ptr @_mm_shufflelo_epi16.__permute_selectors, i64 0, i64 {{[0-9a-zA-Z_%.]+}} +// CHECK-COUNT-4: getelementptr inbounds nuw [4 x i16], ptr @_mm_shufflelo_epi16.__permute_selectors, i64 0, i64 {{[0-9a-zA-Z_%.]+}} // CHECK: call <2 x i64> @vec_perm(unsigned long long vector[2], unsigned long long vector[2], unsigned char vector[16]) void __attribute__((noinline)) diff --git a/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c b/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c index 95dfd1202f1575..4a15fa9f76ceea 100644 --- a/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c +++ b/clang/test/CodeGen/PowerPC/ppc-xmmintrin.c @@ -894,16 +894,16 @@ test_shuffle() { // CHECK: %[[SHR3:[0-9a-zA-Z_.]+]] = ashr i32 %{{[0-9a-zA-Z_.]+}}, 6 // CHECK: %[[AND4:[0-9a-zA-Z_.]+]] = and i32 %[[SHR3]], 3 // CHECK: sext i32 %[[AND4]] to i64 -// CHECK: getelementptr inbounds [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK-LE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 0 // CHECK-BE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 3 -// CHECK: getelementptr inbounds [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK-LE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 1 // CHECK-BE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 2 -// CHECK: getelementptr inbounds [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK-LE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 2 // CHECK-BE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 1 -// CHECK: getelementptr inbounds [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} +// CHECK: getelementptr inbounds nuw [4 x i16], ptr @_mm_shuffle_pi16.__permute_selectors, i64 0, i64 %{{[0-9a-zA-Z_.]+}} // CHECK-LE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 3 // CHECK-BE: getelementptr inbounds [4 x i16], ptr %{{[0-9a-zA-Z_.]+}}, i64 0, i64 0 // CHECK: call <2 x i64> @vec_splats(unsigned long long) @@ -923,14 +923,14 @@ test_shuffle() { // CHECK: %[[SHR3:[0-9a-zA-Z_.]+]] = ashr i32 %{{[0-9a-zA-Z_.]+}}, 6 // CHECK: %[[AND4:[0-9a-zA-Z_.]+]] = and i32 %[[SHR3]], 3 // CHECK: sext i32 %[[AND4]] to i64 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %{{[0-9a-zA-Z_.]+}}, i32 0 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %{{[0-9a-zA-Z_.]+}}, i32 1 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 // CHECK: %[[ADD:[0-9a-zA-Z_.]+]] = add i32 %{{[0-9a-zA-Z_.]+}}, 269488144 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %[[ADD]], i32 2 -// CHECK: getelementptr inbounds [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 +// CHECK: getelementptr inbounds nuw [4 x i32], ptr @_mm_shuffle_ps.__permute_selectors, i64 0, i64 // CHECK: %[[ADD2:[0-9a-zA-Z_.]+]] = add i32 %{{[0-9a-zA-Z_.]+}}, 269488144 // CHECK: insertelement <4 x i32> %{{[0-9a-zA-Z_.]+}}, i32 %[[ADD2]], i32 3 // CHECK: call <4 x float> @vec_perm(float vector[4], float vector[4], unsigned char vector[16]) diff --git a/clang/test/CodeGenCXX/pr45964-decomp-transform.cpp b/clang/test/CodeGenCXX/pr45964-decomp-transform.cpp index f7df110ec01298..bcb2d875dce663 100644 --- a/clang/test/CodeGenCXX/pr45964-decomp-transform.cpp +++ b/clang/test/CodeGenCXX/pr45964-decomp-transform.cpp @@ -16,7 +16,7 @@ void (*d)(){test_transform<0>}; // CHECK-NEXT: [[BODY]]: // CHECK-NEXT: [[CUR:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[NEXT:%.*]], %[[BODY]] ] // CHECK-NEXT: [[DEST:%.*]] = getelementptr inbounds i32, ptr [[BEGIN]], i64 [[CUR]] -// CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds [1 x i32], ptr @a, i64 0, i64 [[CUR]] +// CHECK-NEXT: [[SRC:%.*]] = getelementptr inbounds nuw [1 x i32], ptr @a, i64 0, i64 [[CUR]] // CHECK-NEXT: [[X:%.*]] = load i32, ptr [[SRC]] // CHECK-NEXT: store i32 [[X]], ptr [[DEST]] // CHECK-NEXT: [[NEXT]] = add nuw i64 [[CUR]], 1 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits