From c290c04513d822d1192ed1329527473645535aa0 Mon Sep 17 00:00:00 2001 From: akashi Date: Fri, 21 Jun 2024 00:52:18 +0300 Subject: [PATCH] [CIR][CodeGen] Fix missing 'nsw' flag in add, sub, and mul in binop operator (#677) This PR is to fix the missing **nsw** flag in issue #664 regarding add, mul arithmetic operations. there is also a problem with unary operations such as **Inc ,Dec,Plus,Minus and Not** . which should also have 'nsw' flag [example](https://godbolt.org/z/q3o3jsbe1). This part should need to be fixed through lowering. --- .../CIR/Dialect/Builder/CIRBaseBuilder.h | 39 ++++++++++- clang/include/clang/CIR/Dialect/IR/CIRTypes.h | 2 +- clang/lib/CIR/CodeGen/CIRGenBuilder.h | 19 ++++++ clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp | 67 ++++++++++++++++++- clang/lib/CIR/Dialect/IR/CIRTypes.cpp | 13 ++++ clang/test/CIR/CodeGen/binop.cpp | 4 +- clang/test/CIR/CodeGen/bitint.cpp | 2 +- clang/test/CIR/CodeGen/call.c | 4 +- clang/test/CIR/CodeGen/comma.cpp | 2 +- clang/test/CIR/CodeGen/if-constexpr.cpp | 4 +- clang/test/CIR/CodeGen/lambda.cpp | 2 +- clang/test/CIR/CodeGen/loop.cpp | 18 ++--- clang/test/CIR/CodeGen/sourcelocation.cpp | 31 +++++---- clang/test/CIR/CodeGen/switch.cpp | 4 +- clang/test/CIR/CodeGen/vectype-ext.cpp | 8 +-- clang/test/CIR/CodeGen/vectype.cpp | 2 +- clang/test/CIR/Lowering/vectype.cpp | 4 +- 17 files changed, 178 insertions(+), 47 deletions(-) diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h index cb7bb85617f5..9201f0859be0 100644 --- a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -171,8 +171,21 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return createBinop(lhs, mlir::cir::BinOpKind::Or, rhs); } - mlir::Value createMul(mlir::Value lhs, mlir::Value rhs) { - return createBinop(lhs, mlir::cir::BinOpKind::Mul, rhs); + mlir::Value createMul(mlir::Value lhs, mlir::Value rhs, bool hasNUW = false, + bool hasNSW = false) { + auto op = create(lhs.getLoc(), lhs.getType(), + mlir::cir::BinOpKind::Mul, lhs, rhs); + if (hasNUW) + op.setNoUnsignedWrap(true); + if (hasNSW) + op.setNoSignedWrap(true); + return op; + } + mlir::Value createNSWMul(mlir::Value lhs, mlir::Value rhs) { + return createMul(lhs, rhs, false, true); + } + mlir::Value createNUWAMul(mlir::Value lhs, mlir::Value rhs) { + return createMul(lhs, rhs, true, false); } mlir::Value createMul(mlir::Value lhs, llvm::APInt rhs) { @@ -235,6 +248,28 @@ class CIRBaseBuilderTy : public mlir::OpBuilder { return createSub(lhs, rhs, false, true); } + mlir::Value createNUWSub(mlir::Value lhs, mlir::Value rhs) { + return createSub(lhs, rhs, true, false); + } + + mlir::Value createAdd(mlir::Value lhs, mlir::Value rhs, bool hasNUW = false, + bool hasNSW = false) { + auto op = create(lhs.getLoc(), lhs.getType(), + mlir::cir::BinOpKind::Add, lhs, rhs); + if (hasNUW) + op.setNoUnsignedWrap(true); + if (hasNSW) + op.setNoSignedWrap(true); + return op; + } + + mlir::Value createNSWAdd(mlir::Value lhs, mlir::Value rhs) { + return createAdd(lhs, rhs, false, true); + } + mlir::Value createNUWAdd(mlir::Value lhs, mlir::Value rhs) { + return createAdd(lhs, rhs, true, false); + } + struct BinOpOverflowResults { mlir::Value result; mlir::Value overflow; diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index fc8ba746a4fb..37202322eac2 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -177,7 +177,7 @@ class StructType }; bool isAnyFloatingPointType(mlir::Type t); - +bool isFPOrFPVectorTy(mlir::Type); } // namespace cir } // namespace mlir diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h index a14c719f81f2..0f7d80ff58a1 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuilder.h +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -648,6 +648,25 @@ class CIRGenBuilderTy : public CIRBaseBuilderTy { lhs, rhs); } + mlir::Value createFAdd(mlir::Value lhs, mlir::Value rhs) { + assert(!MissingFeatures::metaDataNode()); + if (IsFPConstrained) + llvm_unreachable("Constrained FP NYI"); + + assert(!MissingFeatures::foldBinOpFMF()); + return create(lhs.getLoc(), mlir::cir::BinOpKind::Add, + lhs, rhs); + } + mlir::Value createFMul(mlir::Value lhs, mlir::Value rhs) { + assert(!MissingFeatures::metaDataNode()); + if (IsFPConstrained) + llvm_unreachable("Constrained FP NYI"); + + assert(!MissingFeatures::foldBinOpFMF()); + return create(lhs.getLoc(), mlir::cir::BinOpKind::Mul, + lhs, rhs); + } + mlir::Value createDynCast(mlir::Location loc, mlir::Value src, mlir::cir::PointerType destType, bool isRefCast, mlir::cir::DynamicCastInfoAttr info) { diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index b969bd9ffdbb..35ec7f0dc5ba 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -1289,6 +1289,38 @@ static mlir::Value buildPointerArithmetic(CIRGenFunction &CGF, } mlir::Value ScalarExprEmitter::buildMul(const BinOpInfo &Ops) { + if (Ops.CompType->isSignedIntegerOrEnumerationType()) { + switch (CGF.getLangOpts().getSignedOverflowBehavior()) { + case LangOptions::SOB_Defined: + if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) + return Builder.createMul(Ops.LHS, Ops.RHS); + [[fallthrough]]; + case LangOptions::SOB_Undefined: + if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) + return Builder.createNSWMul(Ops.LHS, Ops.RHS); + [[fallthrough]]; + case LangOptions::SOB_Trapping: + if (CanElideOverflowCheck(CGF.getContext(), Ops)) + return Builder.createNSWMul(Ops.LHS, Ops.RHS); + llvm_unreachable("NYI"); + } + } + if (Ops.FullType->isConstantMatrixType()) { + llvm_unreachable("NYI"); + } + if (Ops.CompType->isUnsignedIntegerType() && + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && + !CanElideOverflowCheck(CGF.getContext(), Ops)) + llvm_unreachable("NYI"); + + if (mlir::cir::isFPOrFPVectorTy(Ops.LHS.getType())) { + CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures); + return Builder.createFMul(Ops.LHS, Ops.RHS); + } + + if (Ops.isFixedPointOp()) + llvm_unreachable("NYI"); + return Builder.create( CGF.getLoc(Ops.Loc), CGF.getCIRType(Ops.FullType), mlir::cir::BinOpKind::Mul, Ops.LHS, Ops.RHS); @@ -1308,6 +1340,39 @@ mlir::Value ScalarExprEmitter::buildAdd(const BinOpInfo &Ops) { if (Ops.LHS.getType().isa() || Ops.RHS.getType().isa()) return buildPointerArithmetic(CGF, Ops, /*isSubtraction=*/false); + if (Ops.CompType->isSignedIntegerOrEnumerationType()) { + switch (CGF.getLangOpts().getSignedOverflowBehavior()) { + case LangOptions::SOB_Defined: + if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) + return Builder.createAdd(Ops.LHS, Ops.RHS); + [[fallthrough]]; + case LangOptions::SOB_Undefined: + if (!CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) + return Builder.createNSWAdd(Ops.LHS, Ops.RHS); + [[fallthrough]]; + case LangOptions::SOB_Trapping: + if (CanElideOverflowCheck(CGF.getContext(), Ops)) + return Builder.createNSWAdd(Ops.LHS, Ops.RHS); + + llvm_unreachable("NYI"); + } + } + if (Ops.FullType->isConstantMatrixType()) { + llvm_unreachable("NYI"); + } + + if (Ops.CompType->isUnsignedIntegerType() && + CGF.SanOpts.has(SanitizerKind::UnsignedIntegerOverflow) && + !CanElideOverflowCheck(CGF.getContext(), Ops)) + llvm_unreachable("NYI"); + + if (mlir::cir::isFPOrFPVectorTy(Ops.LHS.getType())) { + CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures); + return Builder.createFAdd(Ops.LHS, Ops.RHS); + } + + if (Ops.isFixedPointOp()) + llvm_unreachable("NYI"); return Builder.create( CGF.getLoc(Ops.Loc), CGF.getCIRType(Ops.FullType), @@ -1344,7 +1409,7 @@ mlir::Value ScalarExprEmitter::buildSub(const BinOpInfo &Ops) { !CanElideOverflowCheck(CGF.getContext(), Ops)) llvm_unreachable("NYI"); - if (Ops.CompType->isFloatingType()) { + if (mlir::cir::isFPOrFPVectorTy(Ops.LHS.getType())) { CIRGenFunction::CIRGenFPOptionsRAII FPOptsRAII(CGF, Ops.FPFeatures); return Builder.createFSub(Ops.LHS, Ops.RHS); } diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index 8dcbeb7edc65..51705d5cad1a 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -803,6 +803,19 @@ bool mlir::cir::isAnyFloatingPointType(mlir::Type t) { mlir::cir::LongDoubleType, mlir::cir::FP80Type>(t); } +//===----------------------------------------------------------------------===// +// Floating-point and Float-point Vecotr type helpers +//===----------------------------------------------------------------------===// + +bool mlir::cir::isFPOrFPVectorTy(mlir::Type t) { + + if (isa(t)) { + return isAnyFloatingPointType( + t.dyn_cast().getEltType()); + } + return isAnyFloatingPointType(t); +} + //===----------------------------------------------------------------------===// // FuncType Definitions //===----------------------------------------------------------------------===// diff --git a/clang/test/CIR/CodeGen/binop.cpp b/clang/test/CIR/CodeGen/binop.cpp index 30b54beab761..29f6e89282b0 100644 --- a/clang/test/CIR/CodeGen/binop.cpp +++ b/clang/test/CIR/CodeGen/binop.cpp @@ -14,10 +14,10 @@ void b0(int a, int b) { x = x | b; } -// CHECK: = cir.binop(mul, %3, %4) : !s32i +// CHECK: = cir.binop(mul, %3, %4) nsw : !s32i // CHECK: = cir.binop(div, %6, %7) : !s32i // CHECK: = cir.binop(rem, %9, %10) : !s32i -// CHECK: = cir.binop(add, %12, %13) : !s32i +// CHECK: = cir.binop(add, %12, %13) nsw : !s32i // CHECK: = cir.binop(sub, %15, %16) nsw : !s32i // CHECK: = cir.shift( right, %18 : !s32i, %19 : !s32i) -> !s32i // CHECK: = cir.shift(left, %21 : !s32i, %22 : !s32i) -> !s32i diff --git a/clang/test/CIR/CodeGen/bitint.cpp b/clang/test/CIR/CodeGen/bitint.cpp index 09c133d0e1be..7f7c85ed268c 100644 --- a/clang/test/CIR/CodeGen/bitint.cpp +++ b/clang/test/CIR/CodeGen/bitint.cpp @@ -47,7 +47,7 @@ i10 test_arith(i10 lhs, i10 rhs) { // CHECK: cir.func @_Z10test_arithDB10_S_(%arg0: !cir.int loc({{.+}}), %arg1: !cir.int loc({{.+}})) -> !cir.int // CHECK: %[[#LHS:]] = cir.load %{{.+}} : !cir.ptr>, !cir.int // CHECK-NEXT: %[[#RHS:]] = cir.load %{{.+}} : !cir.ptr>, !cir.int -// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#LHS]], %[[#RHS]]) : !cir.int +// CHECK-NEXT: %{{.+}} = cir.binop(add, %[[#LHS]], %[[#RHS]]) nsw : !cir.int // CHECK: } void Size1ExtIntParam(unsigned _BitInt(1) A) { diff --git a/clang/test/CIR/CodeGen/call.c b/clang/test/CIR/CodeGen/call.c index 8129288bbd68..2c3d5cfa151e 100644 --- a/clang/test/CIR/CodeGen/call.c +++ b/clang/test/CIR/CodeGen/call.c @@ -26,7 +26,7 @@ void d(void) { // CHECK: cir.store %arg1, %1 : !s32i, !cir.ptr // CHECK: %3 = cir.load %0 : !cir.ptr, !s32i // CHECK: %4 = cir.load %1 : !cir.ptr, !s32i -// CHECK: %5 = cir.binop(add, %3, %4) : !s32i +// CHECK: %5 = cir.binop(add, %3, %4) nsw : !s32i // CHECK: cir.store %5, %2 : !s32i, !cir.ptr // CHECK: %6 = cir.load %2 : !cir.ptr, !s32i // CHECK: cir.return %6 @@ -64,7 +64,7 @@ void d(void) { // CXX-NEXT: cir.store %arg1, %1 : !s32i, !cir.ptr // CXX-NEXT: %3 = cir.load %0 : !cir.ptr, !s32i // CXX-NEXT: %4 = cir.load %1 : !cir.ptr, !s32i -// CXX-NEXT: %5 = cir.binop(add, %3, %4) : !s32i +// CXX-NEXT: %5 = cir.binop(add, %3, %4) nsw : !s32i // CXX-NEXT: cir.store %5, %2 : !s32i, !cir.ptr // CXX-NEXT: %6 = cir.load %2 : !cir.ptr, !s32i // CXX-NEXT: cir.return %6 diff --git a/clang/test/CIR/CodeGen/comma.cpp b/clang/test/CIR/CodeGen/comma.cpp index fd3f11f81d02..368b0e1bd18d 100644 --- a/clang/test/CIR/CodeGen/comma.cpp +++ b/clang/test/CIR/CodeGen/comma.cpp @@ -12,7 +12,7 @@ int c0() { // CHECK: %[[#A:]] = cir.alloca !s32i, !cir.ptr, ["a", init] // CHECK: %[[#B:]] = cir.alloca !s32i, !cir.ptr, ["b", init] // CHECK: %[[#LOADED_B:]] = cir.load %[[#B]] : !cir.ptr, !s32i -// CHECK: %[[#]] = cir.binop(add, %[[#LOADED_B]], %[[#]]) : !s32i +// CHECK: %[[#]] = cir.binop(add, %[[#LOADED_B]], %[[#]]) nsw : !s32i // CHECK: %[[#LOADED_A:]] = cir.load %[[#A]] : !cir.ptr, !s32i // CHECK: cir.store %[[#LOADED_A]], %[[#RET]] : !s32i, !cir.ptr diff --git a/clang/test/CIR/CodeGen/if-constexpr.cpp b/clang/test/CIR/CodeGen/if-constexpr.cpp index 1e487389cc62..f980f3100841 100644 --- a/clang/test/CIR/CodeGen/if-constexpr.cpp +++ b/clang/test/CIR/CodeGen/if-constexpr.cpp @@ -66,7 +66,7 @@ void if0() { // CHECK-NEXT: cir.store %4, %2 : !s32i, !cir.ptr loc({{.*}}) // CHECK-NEXT: %5 = cir.const #cir.int<3> : !s32i loc({{.*}}) // CHECK-NEXT: %6 = cir.load %2 : !cir.ptr, !s32i loc({{.*}}) -// CHECK-NEXT: %7 = cir.binop(mul, %5, %6) : !s32i loc({{.*}}) +// CHECK-NEXT: %7 = cir.binop(mul, %5, %6) nsw : !s32i loc({{.*}}) // CHECK-NEXT: cir.store %7, %3 : !s32i, !cir.ptr loc({{.*}}) // CHECK-NEXT: } loc({{.*}}) // CHECK-NEXT: cir.scope { @@ -84,7 +84,7 @@ void if0() { // CHECK-NEXT: cir.store %4, %2 : !s32i, !cir.ptr loc({{.*}}) // CHECK-NEXT: %5 = cir.const #cir.int<10> : !s32i loc({{.*}}) // CHECK-NEXT: %6 = cir.load %2 : !cir.ptr, !s32i loc({{.*}}) -// CHECK-NEXT: %7 = cir.binop(mul, %5, %6) : !s32i loc({{.*}}) +// CHECK-NEXT: %7 = cir.binop(mul, %5, %6) nsw : !s32i loc({{.*}}) // CHECK-NEXT: cir.store %7, %3 : !s32i, !cir.ptr loc({{.*}}) // CHECK-NEXT: } loc({{.*}}) // CHECK-NEXT: cir.scope { diff --git a/clang/test/CIR/CodeGen/lambda.cpp b/clang/test/CIR/CodeGen/lambda.cpp index 976b538a2129..7f243167dff4 100644 --- a/clang/test/CIR/CodeGen/lambda.cpp +++ b/clang/test/CIR/CodeGen/lambda.cpp @@ -30,7 +30,7 @@ void l0() { // CHECK: %3 = cir.load %2 : !cir.ptr>, !cir.ptr // CHECK: %4 = cir.load %3 : !cir.ptr, !s32i // CHECK: %5 = cir.const #cir.int<1> : !s32i -// CHECK: %6 = cir.binop(add, %4, %5) : !s32i +// CHECK: %6 = cir.binop(add, %4, %5) nsw : !s32i // CHECK: %7 = cir.get_member %1[0] {name = "i"} : !cir.ptr -> !cir.ptr> // CHECK: %8 = cir.load %7 : !cir.ptr>, !cir.ptr // CHECK: cir.store %6, %8 : !s32i, !cir.ptr diff --git a/clang/test/CIR/CodeGen/loop.cpp b/clang/test/CIR/CodeGen/loop.cpp index 092c8b952472..64909759fd25 100644 --- a/clang/test/CIR/CodeGen/loop.cpp +++ b/clang/test/CIR/CodeGen/loop.cpp @@ -27,13 +27,13 @@ void l1() { // CHECK-NEXT: } body { // CHECK-NEXT: %4 = cir.load %0 : !cir.ptr, !s32i // CHECK-NEXT: %5 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %6 = cir.binop(add, %4, %5) : !s32i +// CHECK-NEXT: %6 = cir.binop(add, %4, %5) nsw : !s32i // CHECK-NEXT: cir.store %6, %0 : !s32i, !cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } step { // CHECK-NEXT: %4 = cir.load %2 : !cir.ptr, !s32i // CHECK-NEXT: %5 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %6 = cir.binop(add, %4, %5) : !s32i +// CHECK-NEXT: %6 = cir.binop(add, %4, %5) nsw : !s32i // CHECK-NEXT: cir.store %6, %2 : !s32i, !cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } @@ -59,7 +59,7 @@ void l2(bool cond) { // CHECK-NEXT: } do { // CHECK-NEXT: %3 = cir.load %1 : !cir.ptr, !s32i // CHECK-NEXT: %4 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %5 = cir.binop(add, %3, %4) : !s32i +// CHECK-NEXT: %5 = cir.binop(add, %3, %4) nsw : !s32i // CHECK-NEXT: cir.store %5, %1 : !s32i, !cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } @@ -71,7 +71,7 @@ void l2(bool cond) { // CHECK-NEXT: } do { // CHECK-NEXT: %3 = cir.load %1 : !cir.ptr, !s32i // CHECK-NEXT: %4 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %5 = cir.binop(add, %3, %4) : !s32i +// CHECK-NEXT: %5 = cir.binop(add, %3, %4) nsw : !s32i // CHECK-NEXT: cir.store %5, %1 : !s32i, !cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } @@ -84,7 +84,7 @@ void l2(bool cond) { // CHECK-NEXT: } do { // CHECK-NEXT: %3 = cir.load %1 : !cir.ptr, !s32i // CHECK-NEXT: %4 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %5 = cir.binop(add, %3, %4) : !s32i +// CHECK-NEXT: %5 = cir.binop(add, %3, %4) nsw : !s32i // CHECK-NEXT: cir.store %5, %1 : !s32i, !cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } @@ -108,7 +108,7 @@ void l3(bool cond) { // CHECK-NEXT: cir.do { // CHECK-NEXT: %3 = cir.load %1 : !cir.ptr, !s32i // CHECK-NEXT: %4 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %5 = cir.binop(add, %3, %4) : !s32i +// CHECK-NEXT: %5 = cir.binop(add, %3, %4) nsw : !s32i // CHECK-NEXT: cir.store %5, %1 : !s32i, !cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } while { @@ -120,7 +120,7 @@ void l3(bool cond) { // CHECK-NEXT: cir.do { // CHECK-NEXT: %3 = cir.load %1 : !cir.ptr, !s32i // CHECK-NEXT: %4 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %5 = cir.binop(add, %3, %4) : !s32i +// CHECK-NEXT: %5 = cir.binop(add, %3, %4) nsw : !s32i // CHECK-NEXT: cir.store %5, %1 : !s32i, !cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } while { @@ -132,7 +132,7 @@ void l3(bool cond) { // CHECK-NEXT: cir.do { // CHECK-NEXT: %3 = cir.load %1 : !cir.ptr, !s32i // CHECK-NEXT: %4 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %5 = cir.binop(add, %3, %4) : !s32i +// CHECK-NEXT: %5 = cir.binop(add, %3, %4) nsw : !s32i // CHECK-NEXT: cir.store %5, %1 : !s32i, !cir.ptr // CHECK-NEXT: cir.yield // CHECK-NEXT: } while { @@ -159,7 +159,7 @@ void l4() { // CHECK-NEXT: } do { // CHECK-NEXT: %4 = cir.load %0 : !cir.ptr, !s32i // CHECK-NEXT: %5 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %6 = cir.binop(add, %4, %5) : !s32i +// CHECK-NEXT: %6 = cir.binop(add, %4, %5) nsw : !s32i // CHECK-NEXT: cir.store %6, %0 : !s32i, !cir.ptr // CHECK-NEXT: cir.scope { // CHECK-NEXT: %10 = cir.load %0 : !cir.ptr, !s32i diff --git a/clang/test/CIR/CodeGen/sourcelocation.cpp b/clang/test/CIR/CodeGen/sourcelocation.cpp index cc456e6cf58b..85dd678cf52f 100644 --- a/clang/test/CIR/CodeGen/sourcelocation.cpp +++ b/clang/test/CIR/CodeGen/sourcelocation.cpp @@ -28,24 +28,24 @@ int s0(int a, int b) { // CIR: cir.store %arg1, %1 : !s32i, !cir.ptr loc(#loc9) // CIR: %4 = cir.load %0 : !cir.ptr, !s32i loc(#loc10) // CIR: %5 = cir.load %1 : !cir.ptr, !s32i loc(#loc8) -// CIR: %6 = cir.binop(add, %4, %5) : !s32i loc(#loc24) +// CIR: %6 = cir.binop(add, %4, %5) nsw : !s32i loc(#loc10) // CIR: cir.store %6, %3 : !s32i, !cir.ptr loc(#loc23) // CIR: cir.scope { // CIR: %9 = cir.load %3 : !cir.ptr, !s32i loc(#loc13) // CIR: %10 = cir.const #cir.int<0> : !s32i loc(#loc14) -// CIR: %11 = cir.cmp(gt, %9, %10) : !s32i, !cir.bool loc(#loc26) +// CIR: %11 = cir.cmp(gt, %9, %10) : !s32i, !cir.bool loc(#loc25) // CIR: cir.if %11 { // CIR: %12 = cir.const #cir.int<0> : !s32i loc(#loc16) -// CIR: cir.store %12, %3 : !s32i, !cir.ptr loc(#loc28) +// CIR: cir.store %12, %3 : !s32i, !cir.ptr loc(#loc27) // CIR: } else { // CIR: %12 = cir.const #cir.int<1> : !s32i loc(#loc12) -// CIR: cir.store %12, %3 : !s32i, !cir.ptr loc(#loc29) -// CIR: } loc(#loc27) -// CIR: } loc(#loc25) +// CIR: cir.store %12, %3 : !s32i, !cir.ptr loc(#loc28) +// CIR: } loc(#loc26) +// CIR: } loc(#loc24) // CIR: %7 = cir.load %3 : !cir.ptr, !s32i loc(#loc18) -// CIR: cir.store %7, %2 : !s32i, !cir.ptr loc(#loc30) -// CIR: %8 = cir.load %2 : !cir.ptr, !s32i loc(#loc30) -// CIR: cir.return %8 : !s32i loc(#loc30) +// CIR: cir.store %7, %2 : !s32i, !cir.ptr loc(#loc29) +// CIR: %8 = cir.load %2 : !cir.ptr, !s32i loc(#loc29) +// CIR: cir.return %8 : !s32i loc(#loc29) // CIR: } loc(#loc20) // CIR: } loc(#loc) // CIR: #loc = loc("{{.*}}sourcelocation.cpp":0:0) @@ -66,13 +66,12 @@ int s0(int a, int b) { // CIR: #loc19 = loc("{{.*}}sourcelocation.cpp":12:3) // CIR: #loc20 = loc(fused[#loc1, #loc2]) // CIR: #loc23 = loc(fused[#loc7, #loc8]) -// CIR: #loc24 = loc(fused[#loc10, #loc8]) -// CIR: #loc25 = loc(fused[#loc11, #loc12]) -// CIR: #loc26 = loc(fused[#loc13, #loc14]) -// CIR: #loc27 = loc(fused[#loc15, #loc16, #loc17, #loc12]) -// CIR: #loc28 = loc(fused[#loc15, #loc16]) -// CIR: #loc29 = loc(fused[#loc17, #loc12]) -// CIR: #loc30 = loc(fused[#loc19, #loc18]) +// CIR: #loc24 = loc(fused[#loc11, #loc12]) +// CIR: #loc25 = loc(fused[#loc13, #loc14]) +// CIR: #loc26 = loc(fused[#loc15, #loc16, #loc17, #loc12]) +// CIR: #loc27 = loc(fused[#loc15, #loc16]) +// CIR: #loc28 = loc(fused[#loc17, #loc12]) +// CIR: #loc29 = loc(fused[#loc19, #loc18]) // LLVM: ModuleID = '{{.*}}sourcelocation.cpp' diff --git a/clang/test/CIR/CodeGen/switch.cpp b/clang/test/CIR/CodeGen/switch.cpp index 367656d1965a..74b1312fd229 100644 --- a/clang/test/CIR/CodeGen/switch.cpp +++ b/clang/test/CIR/CodeGen/switch.cpp @@ -20,7 +20,7 @@ void sw1(int a) { // CHECK-NEXT: case (equal, 0) { // CHECK-NEXT: %4 = cir.load %1 : !cir.ptr, !s32i // CHECK-NEXT: %5 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %6 = cir.binop(add, %4, %5) : !s32i +// CHECK-NEXT: %6 = cir.binop(add, %4, %5) nsw : !s32i // CHECK-NEXT: cir.store %6, %1 : !s32i, !cir.ptr // CHECK-NEXT: cir.break // CHECK-NEXT: }, @@ -32,7 +32,7 @@ void sw1(int a) { // CHECK-NEXT: %4 = cir.alloca !s32i, !cir.ptr, ["yolo", init] // CHECK-NEXT: %5 = cir.load %1 : !cir.ptr, !s32i // CHECK-NEXT: %6 = cir.const #cir.int<1> : !s32i -// CHECK-NEXT: %7 = cir.binop(add, %5, %6) : !s32i +// CHECK-NEXT: %7 = cir.binop(add, %5, %6) nsw : !s32i // CHECK-NEXT: cir.store %7, %1 : !s32i, !cir.ptr // CHECK-NEXT: %8 = cir.const #cir.int<100> : !s32i // CHECK-NEXT: cir.store %8, %4 : !s32i, !cir.ptr diff --git a/clang/test/CIR/CodeGen/vectype-ext.cpp b/clang/test/CIR/CodeGen/vectype-ext.cpp index a4700f4101b6..f41e4c78e0bd 100644 --- a/clang/test/CIR/CodeGen/vectype-ext.cpp +++ b/clang/test/CIR/CodeGen/vectype-ext.cpp @@ -25,7 +25,7 @@ void vector_int_test(int x) { // CIR: %{{[0-9]+}} = cir.vec.create(%{{[0-9]+}}, %{{[0-9]+}}, %{{[0-9]+}}, %{{[0-9]+}} : !s32i, !s32i, !s32i, !s32i) : !cir.vector // LLVM: %[[#X1:]] = load i32, ptr %{{[0-9]+}}, align 4 // LLVM-NEXT: %[[#X2:]] = load i32, ptr %{{[0-9]+}}, align 4 - // LLVM-NEXT: %[[#SUM:]] = add i32 %[[#X2]], 1 + // LLVM-NEXT: %[[#SUM:]] = add nsw i32 %[[#X2]], 1 // LLVM-NEXT: %[[#VEC1:]] = insertelement <4 x i32> undef, i32 %[[#X1]], i64 0 // LLVM-NEXT: %[[#VEC2:]] = insertelement <4 x i32> %[[#VEC1]], i32 5, i64 1 // LLVM-NEXT: %[[#VEC3:]] = insertelement <4 x i32> %[[#VEC2]], i32 6, i64 2 @@ -38,7 +38,7 @@ void vector_int_test(int x) { // CIR: %{{[0-9]+}} = cir.vec.create(%{{[0-9]+}}, %{{[0-9]+}}, %[[#zero]], %[[#zero]] : !s32i, !s32i, !s32i, !s32i) : !cir.vector // LLVM: %[[#X1:]] = load i32, ptr %{{[0-9]+}}, align 4 // LLVM-NEXT: %[[#X2:]] = load i32, ptr %{{[0-9]+}}, align 4 - // LLVM-NEXT: %[[#SUM:]] = add i32 %[[#X2]], 1 + // LLVM-NEXT: %[[#SUM:]] = add nsw i32 %[[#X2]], 1 // LLVM-NEXT: %[[#VEC1:]] = insertelement <4 x i32> undef, i32 %[[#X1]], i64 0 // LLVM-NEXT: %[[#VEC2:]] = insertelement <4 x i32> %[[#VEC1]], i32 %[[#SUM]], i64 1 // LLVM-NEXT: %[[#VEC3:]] = insertelement <4 x i32> %[[#VEC2]], i32 0, i64 2 @@ -84,14 +84,14 @@ void vector_int_test(int x) { a[x] += a[0]; // CIR: %[[#RHSCA:]] = cir.vec.extract %{{[0-9]+}}[%{{[0-9]+}} : !s32i] : !cir.vector // CIR: %[[#LHSCA:]] = cir.vec.extract %{{[0-9]+}}[%{{[0-9]+}} : !s32i] : !cir.vector - // CIR: %[[#SUMCA:]] = cir.binop(add, %[[#LHSCA]], %[[#RHSCA]]) : !s32i + // CIR: %[[#SUMCA:]] = cir.binop(add, %[[#LHSCA]], %[[#RHSCA]]) nsw : !s32i // CIR: cir.vec.insert %[[#SUMCA]], %{{[0-9]+}}[%{{[0-9]+}} : !s32i] : !cir.vector // LLVM: %[[#A1:]] = load <4 x i32>, ptr %{{[0-9]+}}, align 16 // LLVM-NEXT: %[[#RHSCA:]] = extractelement <4 x i32> %[[#A1]], i32 0 // LLVM-NEXT: %[[#X:]] = load i32, ptr %{{[0-9]+}}, align 4 // LLVM-NEXT: %[[#A2:]] = load <4 x i32>, ptr %{{[0-9]+}}, align 16 // LLVM-NEXT: %[[#LHSCA:]] = extractelement <4 x i32> %[[#A2]], i32 %[[#X]] - // LLVM-NEXT: %[[#SUMCA:]] = add i32 %[[#LHSCA]], %[[#RHSCA]] + // LLVM-NEXT: %[[#SUMCA:]] = add nsw i32 %[[#LHSCA]], %[[#RHSCA]] // LLVM-NEXT: %[[#A3:]] = load <4 x i32>, ptr %{{[0-9]+}}, align 16 // LLVM-NEXT: %[[#RES:]] = insertelement <4 x i32> %[[#A3]], i32 %[[#SUMCA]], i32 %[[#X]] // LLVM-NEXT: store <4 x i32> %[[#RES]], ptr %{{[0-9]+}}, align 16 diff --git a/clang/test/CIR/CodeGen/vectype.cpp b/clang/test/CIR/CodeGen/vectype.cpp index db31bd8dcf7b..fb3e76d9913b 100644 --- a/clang/test/CIR/CodeGen/vectype.cpp +++ b/clang/test/CIR/CodeGen/vectype.cpp @@ -49,7 +49,7 @@ void vector_int_test(int x) { // CHECK: %[[#LOADCAIDX2:]] = cir.load %{{[0-9]+}} : !cir.ptr, !s32i // CHECK: %[[#LOADCAVEC3:]] = cir.load %{{[0-9]+}} : !cir.ptr>, !cir.vector // CHECK: %[[#LHSCA:]] = cir.vec.extract %[[#LOADCAVEC3]][%[[#LOADCAIDX2]] : !s32i] : !cir.vector - // CHECK: %[[#SUMCA:]] = cir.binop(add, %[[#LHSCA]], %[[#RHSCA]]) : !s32i + // CHECK: %[[#SUMCA:]] = cir.binop(add, %[[#LHSCA]], %[[#RHSCA]]) nsw : !s32i // CHECK: %[[#LOADCAVEC4:]] = cir.load %{{[0-9]+}} : !cir.ptr>, !cir.vector // CHECK: %[[#RESULTCAVEC:]] = cir.vec.insert %[[#SUMCA]], %[[#LOADCAVEC4]][%[[#LOADCAIDX2]] : !s32i] : !cir.vector // CHECK: cir.store %[[#RESULTCAVEC]], %{{[0-9]+}} : !cir.vector, !cir.ptr> diff --git a/clang/test/CIR/Lowering/vectype.cpp b/clang/test/CIR/Lowering/vectype.cpp index 25077a1cb85e..40a11fa56996 100644 --- a/clang/test/CIR/Lowering/vectype.cpp +++ b/clang/test/CIR/Lowering/vectype.cpp @@ -34,7 +34,7 @@ void vector_int_test(int x) { // CHECK: %[[#T45:]] = llvm.mlir.constant(6 : i32) : i32 // CHECK: %[[#T46:]] = llvm.load %[[#T1]] {alignment = 4 : i64} : !llvm.ptr -> i32 // CHECK: %[[#T47:]] = llvm.mlir.constant(1 : i32) : i32 - // CHECK: %[[#T48:]] = llvm.add %[[#T46]], %[[#T47]] : i32 + // CHECK: %[[#T48:]] = llvm.add %[[#T46]], %[[#T47]] overflow : i32 // CHECK: %[[#T49:]] = llvm.mlir.undef : vector<4xi32> // CHECK: %[[#T50:]] = llvm.mlir.constant(0 : i64) : i64 // CHECK: %[[#T51:]] = llvm.insertelement %[[#T43]], %[[#T49]][%[[#T50]] : i64] : vector<4xi32> @@ -81,7 +81,7 @@ void vector_int_test(int x) { // CHECK: %[[#LOADCAIDX2:]] = llvm.load %{{[0-9]+}} {alignment = 4 : i64} : !llvm.ptr -> i32 // CHECK: %[[#LOADCAVEC3:]] = llvm.load %{{[0-9]+}} {alignment = 16 : i64} : !llvm.ptr -> vector<4xi32> // CHECK: %[[#LHSCA:]] = llvm.extractelement %[[#LOADCAVEC3:]][%[[#LOADCAIDX2:]] : i32] : vector<4xi32> - // CHECK: %[[#SUMCA:]] = llvm.add %[[#LHSCA:]], %[[#RHSCA:]] : i32 + // CHECK: %[[#SUMCA:]] = llvm.add %[[#LHSCA:]], %[[#RHSCA:]] overflow : i32 // CHECK: %[[#LOADCAVEC4:]] = llvm.load %{{[0-9]+}} {alignment = 16 : i64} : !llvm.ptr -> vector<4xi32> // CHECK: %[[#RESULTCAVEC:]] = llvm.insertelement %[[#SUMCA:]], %[[#LOADCAVEC4:]][%[[#LOADCAIDX2:]] : i32] : vector<4xi32> // CHECK: llvm.store %[[#RESULTCAVEC:]], %{{[0-9]+}} {alignment = 16 : i64} : vector<4xi32>, !llvm.ptr