Skip to content

Commit

Permalink
[ConstExpr] Don't create div/rem expressions
Browse files Browse the repository at this point in the history
This removes creation of udiv/sdiv/urem/srem constant expressions,
in preparation for their removal. I've added a
ConstantExpr::isDesirableBinOp() predicate to determine whether
an expression should be created for a certain operator.

With this patch, div/rem expressions can still be created through
explicit IR/bitcode, forbidding them entirely will be the next step.

Differential Revision: https://reviews.llvm.org/D128820
  • Loading branch information
nikic committed Jul 5, 2022
1 parent f10d271 commit 935570b
Show file tree
Hide file tree
Showing 18 changed files with 124 additions and 57 deletions.
6 changes: 3 additions & 3 deletions clang/test/CodeGenCUDA/managed-var.cu
Expand Up @@ -144,9 +144,9 @@ float load3() {
// HOST: %3 = getelementptr inbounds [100 x %struct.vec], [100 x %struct.vec]* %2, i64 0, i64 1, i32 1
// HOST: %4 = ptrtoint float* %3 to i64
// HOST: %5 = sub i64 %4, %1
// HOST: %6 = sdiv exact i64 %5, 4
// HOST: %7 = sitofp i64 %6 to float
// HOST: ret float %7
// HOST: %sub.ptr.div = sdiv exact i64 %5, 4
// HOST: %conv = sitofp i64 %sub.ptr.div to float
// HOST: ret float %conv
float addr_taken2() {
return (float)reinterpret_cast<long>(&(v2[1].y)-&(v[1].x));
}
Expand Down
3 changes: 2 additions & 1 deletion clang/test/OpenMP/target_data_codegen.cpp
Expand Up @@ -152,7 +152,8 @@ void foo(int arg) {
// CK1-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to double***
// CK1-DAG: store [[ST]]* @gb, [[ST]]** [[CBP0]]
// CK1-DAG: store double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), double*** [[CP0]]
// CK1-DAG: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
// CK1-DAG: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1-DAG: store i64 [[DIV]], i64* [[PS0]],

// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
// CK1-DAG: [[P1:%.+]] = getelementptr inbounds {{.+}}[[P]], i{{.+}} 0, i{{.+}} 1
Expand Down
3 changes: 2 additions & 1 deletion clang/test/OpenMP/target_enter_data_codegen.cpp
Expand Up @@ -158,7 +158,8 @@ void foo(int arg) {
// CK1-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to double***
// CK1-DAG: store [[ST]]* @gb, [[ST]]** [[CBP0]]
// CK1-DAG: store double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), double*** [[CP0]]
// CK1-DAG: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[S0]],
// CK1-DAG: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1-DAG: store i64 [[DIV]], i64* [[S0]],


// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
Expand Down
3 changes: 2 additions & 1 deletion clang/test/OpenMP/target_enter_data_depend_codegen.cpp
Expand Up @@ -284,14 +284,15 @@ void foo(int arg) {
{++arg;}

// Region 04
// CK1: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1: [[BP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0
// CK1: [[BP0_BC:%.+]] = bitcast i8** [[BP0]] to %struct.ST**
// CK1: store %struct.ST* @gb, %struct.ST** [[BP0_BC]],
// CK1: [[P0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%.+]], i32 0, i32 0
// CK1: [[P0_BC:%.+]] = bitcast i8** [[P0]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[P0_BC]],
// CK1: [[PS0:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[PS:%.+]], i32 0, i32 0
// CK1: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
// CK1: store i64 [[DIV]], i64* [[PS0]],
// CK1: [[BP1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
// CK1: [[BP1_BC:%.+]] = bitcast i8** [[BP1]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[BP1_BC]],
Expand Down
3 changes: 2 additions & 1 deletion clang/test/OpenMP/target_exit_data_codegen.cpp
Expand Up @@ -157,7 +157,8 @@ void foo(int arg) {
// CK1-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to double***
// CK1-DAG: store [[ST]]* @gb, [[ST]]** [[CBP0]]
// CK1-DAG: store double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), double*** [[CP0]]
// CK1-DAG: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
// CK1-DAG: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1-DAG: store i64 [[DIV]], i64* [[PS0]],


// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
Expand Down
3 changes: 2 additions & 1 deletion clang/test/OpenMP/target_exit_data_depend_codegen.cpp
Expand Up @@ -284,14 +284,15 @@ void foo(int arg) {
{++arg;}

// Region 04
// CK1: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1: [[BP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0
// CK1: [[BP0_BC:%.+]] = bitcast i8** [[BP0]] to %struct.ST**
// CK1: store %struct.ST* @gb, %struct.ST** [[BP0_BC]],
// CK1: [[P0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%.+]], i32 0, i32 0
// CK1: [[P0_BC:%.+]] = bitcast i8** [[P0]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[P0_BC]],
// CK1: [[PS0:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[PS:%.+]], i32 0, i32 0
// CK1: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
// CK1: store i64 [[DIV]], i64* [[PS0]],
// CK1: [[BP1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
// CK1: [[BP1_BC:%.+]] = bitcast i8** [[BP1]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[BP1_BC]],
Expand Down
3 changes: 2 additions & 1 deletion clang/test/OpenMP/target_update_codegen.cpp
Expand Up @@ -147,7 +147,8 @@ void foo(int arg) {
// CK1-DAG: [[CP0:%.+]] = bitcast i8** [[P0]] to double***
// CK1-DAG: store [[ST]]* @gb, [[ST]]** [[CBP0]]
// CK1-DAG: store double** getelementptr inbounds ([[ST]], [[ST]]* @gb, i32 0, i32 1), double*** [[CP0]]
// CK1-DAG: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
// CK1-DAG: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1-DAG: store i64 [[DIV]], i64* [[PS0]],


// CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BP]], i{{.+}} 0, i{{.+}} 1
Expand Down
3 changes: 2 additions & 1 deletion clang/test/OpenMP/target_update_depend_codegen.cpp
Expand Up @@ -284,14 +284,15 @@ void foo(int arg) {
{++arg;}

// Region 04
// CK1: [[DIV:%.+]] = sdiv exact i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)
// CK1: [[BP0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP:%.+]], i32 0, i32 0
// CK1: [[BP0_BC:%.+]] = bitcast i8** [[BP0]] to %struct.ST**
// CK1: store %struct.ST* @gb, %struct.ST** [[BP0_BC]],
// CK1: [[P0:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[P:%.+]], i32 0, i32 0
// CK1: [[P0_BC:%.+]] = bitcast i8** [[P0]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[P0_BC]],
// CK1: [[PS0:%.+]] = getelementptr inbounds [2 x i64], [2 x i64]* [[PS:%.+]], i32 0, i32 0
// CK1: store i64 sdiv exact (i64 sub (i64 ptrtoint (double** getelementptr (double*, double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), i32 1) to i64), i64 ptrtoint (double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1) to i64)), i64 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i64)), i64* [[PS0]],
// CK1: store i64 [[DIV]], i64* [[PS0]],
// CK1: [[BP1:%.+]] = getelementptr inbounds [2 x i8*], [2 x i8*]* [[BP]], i32 0, i32 1
// CK1: [[BP1_BC:%.+]] = bitcast i8** [[BP1]] to double***
// CK1: store double** getelementptr inbounds (%struct.ST, %struct.ST* @gb, i32 0, i32 1), double*** [[BP1_BC]],
Expand Down
32 changes: 21 additions & 11 deletions llvm/include/llvm/Analysis/TargetFolder.h
Expand Up @@ -55,18 +55,24 @@ class TargetFolder final : public IRBuilderFolder {
Value *RHS) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
if (LC && RC)
return Fold(ConstantExpr::get(Opc, LC, RC));
if (LC && RC) {
if (ConstantExpr::isDesirableBinOp(Opc))
return Fold(ConstantExpr::get(Opc, LC, RC));
return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
}
return nullptr;
}

Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
bool IsExact) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
if (LC && RC)
return Fold(ConstantExpr::get(
Opc, LC, RC, IsExact ? PossiblyExactOperator::IsExact : 0));
if (LC && RC) {
if (ConstantExpr::isDesirableBinOp(Opc))
return Fold(ConstantExpr::get(
Opc, LC, RC, IsExact ? PossiblyExactOperator::IsExact : 0));
return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
}
return nullptr;
}

Expand All @@ -75,12 +81,15 @@ class TargetFolder final : public IRBuilderFolder {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
if (LC && RC) {
unsigned Flags = 0;
if (HasNUW)
Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
if (HasNSW)
Flags |= OverflowingBinaryOperator::NoSignedWrap;
return Fold(ConstantExpr::get(Opc, LC, RC, Flags));
if (ConstantExpr::isDesirableBinOp(Opc)) {
unsigned Flags = 0;
if (HasNUW)
Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
if (HasNSW)
Flags |= OverflowingBinaryOperator::NoSignedWrap;
return Fold(ConstantExpr::get(Opc, LC, RC, Flags));
}
return ConstantFoldBinaryOpOperands(Opc, LC, RC, DL);
}
return nullptr;
}
Expand All @@ -89,6 +98,7 @@ class TargetFolder final : public IRBuilderFolder {
FastMathFlags FMF) const override {
return FoldBinOp(Opc, LHS, RHS);
}

Value *FoldICmp(CmpInst::Predicate P, Value *LHS, Value *RHS) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
Expand Down
31 changes: 20 additions & 11 deletions llvm/include/llvm/IR/ConstantFolder.h
Expand Up @@ -44,18 +44,24 @@ class ConstantFolder final : public IRBuilderFolder {
Value *RHS) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
if (LC && RC)
return ConstantExpr::get(Opc, LC, RC);
if (LC && RC) {
if (ConstantExpr::isDesirableBinOp(Opc))
return ConstantExpr::get(Opc, LC, RC);
return ConstantFoldBinaryInstruction(Opc, LC, RC);
}
return nullptr;
}

Value *FoldExactBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS,
bool IsExact) const override {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
if (LC && RC)
return ConstantExpr::get(Opc, LC, RC,
IsExact ? PossiblyExactOperator::IsExact : 0);
if (LC && RC) {
if (ConstantExpr::isDesirableBinOp(Opc))
return ConstantExpr::get(Opc, LC, RC,
IsExact ? PossiblyExactOperator::IsExact : 0);
return ConstantFoldBinaryInstruction(Opc, LC, RC);
}
return nullptr;
}

Expand All @@ -64,12 +70,15 @@ class ConstantFolder final : public IRBuilderFolder {
auto *LC = dyn_cast<Constant>(LHS);
auto *RC = dyn_cast<Constant>(RHS);
if (LC && RC) {
unsigned Flags = 0;
if (HasNUW)
Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
if (HasNSW)
Flags |= OverflowingBinaryOperator::NoSignedWrap;
return ConstantExpr::get(Opc, LC, RC, Flags);
if (ConstantExpr::isDesirableBinOp(Opc)) {
unsigned Flags = 0;
if (HasNUW)
Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
if (HasNSW)
Flags |= OverflowingBinaryOperator::NoSignedWrap;
return ConstantExpr::get(Opc, LC, RC, Flags);
}
return ConstantFoldBinaryInstruction(Opc, LC, RC);
}
return nullptr;
}
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/IR/Constants.h
Expand Up @@ -1341,6 +1341,10 @@ class ConstantExpr : public Constant {
/// would make it harder to remove ConstantExprs altogether.
Instruction *getAsInstruction(Instruction *InsertBefore = nullptr) const;

/// Whether creating a constant expression for this binary operator is
/// desirable.
static bool isDesirableBinOp(unsigned Opcode);

/// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == ConstantExprVal;
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Analysis/ConstantFolding.cpp
Expand Up @@ -30,6 +30,7 @@
#include "llvm/Analysis/VectorUtils.h"
#include "llvm/Config/config.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/ConstantFold.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
Expand Down Expand Up @@ -1343,7 +1344,9 @@ Constant *llvm::ConstantFoldBinaryOpOperands(unsigned Opcode, Constant *LHS,
if (Constant *C = SymbolicallyEvaluateBinop(Opcode, LHS, RHS, DL))
return C;

return ConstantExpr::get(Opcode, LHS, RHS);
if (ConstantExpr::isDesirableBinOp(Opcode))
return ConstantExpr::get(Opcode, LHS, RHS);
return ConstantFoldBinaryInstruction(Opcode, LHS, RHS);
}

Constant *llvm::FlushFPConstant(Constant *Operand, const Instruction *I,
Expand Down
9 changes: 1 addition & 8 deletions llvm/lib/Analysis/ScalarEvolution.cpp
Expand Up @@ -9521,14 +9521,7 @@ static Constant *BuildConstantFromSCEV(const SCEV *V) {
}
return C;
}
case scUDivExpr: {
const SCEVUDivExpr *SU = cast<SCEVUDivExpr>(V);
if (Constant *LHS = BuildConstantFromSCEV(SU->getLHS()))
if (Constant *RHS = BuildConstantFromSCEV(SU->getRHS()))
if (LHS->getType() == RHS->getType())
return ConstantExpr::getUDiv(LHS, RHS);
return nullptr;
}
case scUDivExpr:
case scSMaxExpr:
case scUMaxExpr:
case scSMinExpr:
Expand Down
27 changes: 21 additions & 6 deletions llvm/lib/IR/ConstantFold.cpp
Expand Up @@ -1218,9 +1218,13 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
if (Instruction::isIntDivRem(Opcode) && C2Splat->isNullValue())
return PoisonValue::get(VTy);
if (Constant *C1Splat = C1->getSplatValue()) {
return ConstantVector::getSplat(
VTy->getElementCount(),
ConstantExpr::get(Opcode, C1Splat, C2Splat));
Constant *Res =
ConstantExpr::isDesirableBinOp(Opcode)
? ConstantExpr::get(Opcode, C1Splat, C2Splat)
: ConstantFoldBinaryInstruction(Opcode, C1Splat, C2Splat);
if (!Res)
return nullptr;
return ConstantVector::getSplat(VTy->getElementCount(), Res);
}
}

Expand All @@ -1237,7 +1241,12 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, Constant *C1,
if (Instruction::isIntDivRem(Opcode) && RHS->isNullValue())
return PoisonValue::get(VTy);

Result.push_back(ConstantExpr::get(Opcode, LHS, RHS));
Constant *Res = ConstantExpr::isDesirableBinOp(Opcode)
? ConstantExpr::get(Opcode, LHS, RHS)
: ConstantFoldBinaryInstruction(Opcode, LHS, RHS);
if (!Res)
return nullptr;
Result.push_back(Res);
}

return ConstantVector::get(Result);
Expand Down Expand Up @@ -2218,9 +2227,15 @@ Constant *llvm::ConstantFoldGetElementPtr(Type *PointeeTy, Constant *C,
: cast<FixedVectorType>(CurrIdx->getType())->getNumElements(),
Factor);

NewIdxs[i] = ConstantExpr::getSRem(CurrIdx, Factor);
NewIdxs[i] =
ConstantFoldBinaryInstruction(Instruction::SRem, CurrIdx, Factor);

Constant *Div =
ConstantFoldBinaryInstruction(Instruction::SDiv, CurrIdx, Factor);

Constant *Div = ConstantExpr::getSDiv(CurrIdx, Factor);
// We're working on either ConstantInt or vectors of ConstantInt,
// so these should always fold.
assert(NewIdxs[i] != nullptr && Div != nullptr && "Should have folded");

unsigned CommonExtendedWidth =
std::max(PrevIdx->getType()->getScalarSizeInBits(),
Expand Down
27 changes: 27 additions & 0 deletions llvm/lib/IR/Constants.cpp
Expand Up @@ -2365,6 +2365,33 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
return pImpl->ExprConstants.getOrCreate(C1->getType(), Key);
}

bool ConstantExpr::isDesirableBinOp(unsigned Opcode) {
switch (Opcode) {
case Instruction::UDiv:
case Instruction::SDiv:
case Instruction::URem:
case Instruction::SRem:
return false;
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
case Instruction::FAdd:
case Instruction::FSub:
case Instruction::FMul:
case Instruction::FDiv:
case Instruction::FRem:
return true;
default:
llvm_unreachable("Argument must be binop opcode");
}
}

Constant *ConstantExpr::getSizeOf(Type* Ty) {
// sizeof is implemented as: (i64) gep (Ty*)null, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
Expand Down
5 changes: 4 additions & 1 deletion llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
Expand Up @@ -1543,7 +1543,10 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) {
!ShAmtC->containsConstantExpression()) {
// Canonicalize a shift amount constant operand to modulo the bit-width.
Constant *WidthC = ConstantInt::get(Ty, BitWidth);
Constant *ModuloC = ConstantExpr::getURem(ShAmtC, WidthC);
Constant *ModuloC =
ConstantFoldBinaryOpOperands(Instruction::URem, ShAmtC, WidthC, DL);
if (!ModuloC)
return nullptr;
if (ModuloC != ShAmtC)
return replaceOperand(*II, 2, ModuloC);

Expand Down

0 comments on commit 935570b

Please sign in to comment.