xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/ReplaceConstant.cpp (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
1*e8d8bef9SDimitry Andric //===- ReplaceConstant.cpp - Replace LLVM constant expression--------------===//
2*e8d8bef9SDimitry Andric //
3*e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*e8d8bef9SDimitry Andric //
7*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
8*e8d8bef9SDimitry Andric //
9*e8d8bef9SDimitry Andric // This file implements a utility function for replacing LLVM constant
10*e8d8bef9SDimitry Andric // expressions by instructions.
11*e8d8bef9SDimitry Andric //
12*e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===//
13*e8d8bef9SDimitry Andric 
14*e8d8bef9SDimitry Andric #include "llvm/IR/ReplaceConstant.h"
15*e8d8bef9SDimitry Andric #include "llvm/IR/IRBuilder.h"
16*e8d8bef9SDimitry Andric #include "llvm/IR/Instructions.h"
17*e8d8bef9SDimitry Andric #include "llvm/IR/NoFolder.h"
18*e8d8bef9SDimitry Andric 
19*e8d8bef9SDimitry Andric namespace llvm {
20*e8d8bef9SDimitry Andric // Replace a constant expression by instructions with equivalent operations at
21*e8d8bef9SDimitry Andric // a specified location.
22*e8d8bef9SDimitry Andric Instruction *createReplacementInstr(ConstantExpr *CE, Instruction *Instr) {
23*e8d8bef9SDimitry Andric   IRBuilder<NoFolder> Builder(Instr);
24*e8d8bef9SDimitry Andric   unsigned OpCode = CE->getOpcode();
25*e8d8bef9SDimitry Andric   switch (OpCode) {
26*e8d8bef9SDimitry Andric   case Instruction::GetElementPtr: {
27*e8d8bef9SDimitry Andric     SmallVector<Value *, 4> CEOpVec(CE->operands());
28*e8d8bef9SDimitry Andric     ArrayRef<Value *> CEOps(CEOpVec);
29*e8d8bef9SDimitry Andric     return dyn_cast<Instruction>(
30*e8d8bef9SDimitry Andric         Builder.CreateInBoundsGEP(cast<GEPOperator>(CE)->getSourceElementType(),
31*e8d8bef9SDimitry Andric                                   CEOps[0], CEOps.slice(1)));
32*e8d8bef9SDimitry Andric   }
33*e8d8bef9SDimitry Andric   case Instruction::Add:
34*e8d8bef9SDimitry Andric   case Instruction::Sub:
35*e8d8bef9SDimitry Andric   case Instruction::Mul:
36*e8d8bef9SDimitry Andric   case Instruction::UDiv:
37*e8d8bef9SDimitry Andric   case Instruction::SDiv:
38*e8d8bef9SDimitry Andric   case Instruction::FDiv:
39*e8d8bef9SDimitry Andric   case Instruction::URem:
40*e8d8bef9SDimitry Andric   case Instruction::SRem:
41*e8d8bef9SDimitry Andric   case Instruction::FRem:
42*e8d8bef9SDimitry Andric   case Instruction::Shl:
43*e8d8bef9SDimitry Andric   case Instruction::LShr:
44*e8d8bef9SDimitry Andric   case Instruction::AShr:
45*e8d8bef9SDimitry Andric   case Instruction::And:
46*e8d8bef9SDimitry Andric   case Instruction::Or:
47*e8d8bef9SDimitry Andric   case Instruction::Xor:
48*e8d8bef9SDimitry Andric     return dyn_cast<Instruction>(
49*e8d8bef9SDimitry Andric         Builder.CreateBinOp((Instruction::BinaryOps)OpCode, CE->getOperand(0),
50*e8d8bef9SDimitry Andric                             CE->getOperand(1), CE->getName()));
51*e8d8bef9SDimitry Andric   case Instruction::Trunc:
52*e8d8bef9SDimitry Andric   case Instruction::ZExt:
53*e8d8bef9SDimitry Andric   case Instruction::SExt:
54*e8d8bef9SDimitry Andric   case Instruction::FPToUI:
55*e8d8bef9SDimitry Andric   case Instruction::FPToSI:
56*e8d8bef9SDimitry Andric   case Instruction::UIToFP:
57*e8d8bef9SDimitry Andric   case Instruction::SIToFP:
58*e8d8bef9SDimitry Andric   case Instruction::FPTrunc:
59*e8d8bef9SDimitry Andric   case Instruction::FPExt:
60*e8d8bef9SDimitry Andric   case Instruction::PtrToInt:
61*e8d8bef9SDimitry Andric   case Instruction::IntToPtr:
62*e8d8bef9SDimitry Andric   case Instruction::BitCast:
63*e8d8bef9SDimitry Andric     return dyn_cast<Instruction>(
64*e8d8bef9SDimitry Andric         Builder.CreateCast((Instruction::CastOps)OpCode, CE->getOperand(0),
65*e8d8bef9SDimitry Andric                            CE->getType(), CE->getName()));
66*e8d8bef9SDimitry Andric   default:
67*e8d8bef9SDimitry Andric     llvm_unreachable("Unhandled constant expression!\n");
68*e8d8bef9SDimitry Andric   }
69*e8d8bef9SDimitry Andric }
70*e8d8bef9SDimitry Andric } // namespace llvm
71