llvm.org GIT mirror llvm / 859fff4
Include optional subclass flags, such as inbounds, nsw, etc., in the Constant uniquing tables. This allows distinct ConstantExpr objects with the same operation and different flags. Even though a ConstantExpr "a + b" is either always overflowing or never overflowing (due to being a ConstantExpr), it's still necessary to be able to represent it both with and without overflow flags at the same time within the IR, because the safety of the flag may depend on the context of the use. If the constant really does overflow, it wouldn't ever be safe to use with the flag set, however the use may be in code that is never actually executed. This also makes it possible to merge all the flags tests into a single test. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80998 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 11 years ago
16 changed file(s) with 351 addition(s) and 245 deletion(s). Raw diff Collapse all Expand all
570570 // These private methods are used by the type resolution code to create
571571 // ConstantExprs in intermediate forms.
572572 static Constant *getTy(const Type *Ty, unsigned Opcode,
573 Constant *C1, Constant *C2);
573 Constant *C1, Constant *C2,
574 unsigned Flags = 0);
574575 static Constant *getCompareTy(unsigned short pred, Constant *C1,
575576 Constant *C2);
576577 static Constant *getSelectTy(const Type *Ty,
577578 Constant *C1, Constant *C2, Constant *C3);
578579 static Constant *getGetElementPtrTy(const Type *Ty, Constant *C,
579580 Value* const *Idxs, unsigned NumIdxs);
581 static Constant *getInBoundsGetElementPtrTy(const Type *Ty, Constant *C,
582 Value* const *Idxs,
583 unsigned NumIdxs);
580584 static Constant *getExtractElementTy(const Type *Ty, Constant *Val,
581585 Constant *Idx);
582586 static Constant *getInsertElementTy(const Type *Ty, Constant *Val,
717721 /// get - Return a binary or shift operator constant expression,
718722 /// folding if possible.
719723 ///
720 static Constant *get(unsigned Opcode, Constant *C1, Constant *C2);
724 static Constant *get(unsigned Opcode, Constant *C1, Constant *C2,
725 unsigned Flags = 0);
721726
722727 /// @brief Return an ICmp or FCmp comparison operator constant expression.
723728 static Constant *getCompare(unsigned short pred, Constant *C1, Constant *C2);
199199 static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
200200 const Twine &Name = "") {
201201 BinaryOperator *BO = CreateAdd(V1, V2, Name);
202 cast(BO)->setHasNoSignedWrap(true);
202 BO->setHasNoSignedWrap(true);
203203 return BO;
204204 }
205205 static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
206206 const Twine &Name, BasicBlock *BB) {
207207 BinaryOperator *BO = CreateAdd(V1, V2, Name, BB);
208 cast(BO)->setHasNoSignedWrap(true);
208 BO->setHasNoSignedWrap(true);
209209 return BO;
210210 }
211211 static BinaryOperator *CreateNSWAdd(Value *V1, Value *V2,
212212 const Twine &Name, Instruction *I) {
213213 BinaryOperator *BO = CreateAdd(V1, V2, Name, I);
214 cast(BO)->setHasNoSignedWrap(true);
214 BO->setHasNoSignedWrap(true);
215215 return BO;
216216 }
217217
220220 static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
221221 const Twine &Name = "") {
222222 BinaryOperator *BO = CreateSDiv(V1, V2, Name);
223 cast(BO)->setIsExact(true);
223 BO->setIsExact(true);
224224 return BO;
225225 }
226226 static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
227227 const Twine &Name, BasicBlock *BB) {
228228 BinaryOperator *BO = CreateSDiv(V1, V2, Name, BB);
229 cast(BO)->setIsExact(true);
229 BO->setIsExact(true);
230230 return BO;
231231 }
232232 static BinaryOperator *CreateExactSDiv(Value *V1, Value *V2,
233233 const Twine &Name, Instruction *I) {
234234 BinaryOperator *BO = CreateSDiv(V1, V2, Name, I);
235 cast(BO)->setIsExact(true);
235 BO->setIsExact(true);
236236 return BO;
237237 }
238238
285285 /// cannot be reversed (ie, it's a Div), then return true.
286286 ///
287287 bool swapOperands();
288
289 /// setHasNoUnsignedWrap - Set or clear the nsw flag on this instruction,
290 /// which must be an operator which supports this flag. See LangRef.html
291 /// for the meaning of this flag.
292 void setHasNoUnsignedWrap(bool);
293
294 /// setHasNoSignedWrap - Set or clear the nsw flag on this instruction,
295 /// which must be an operator which supports this flag. See LangRef.html
296 /// for the meaning of this flag.
297 void setHasNoSignedWrap(bool);
298
299 /// setIsExact - Set or clear the exact flag on this instruction,
300 /// which must be an operator which supports this flag. See LangRef.html
301 /// for the meaning of this flag.
302 void setIsExact(bool);
288303
289304 // Methods for support type inquiry through isa, cast, and dyn_cast:
290305 static inline bool classof(const BinaryOperator *) { return true; }
495495 Instruction *InsertBefore = 0) {
496496 GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
497497 NameStr, InsertBefore);
498 cast(GEP)->setIsInBounds(true);
498 GEP->setIsInBounds(true);
499499 return GEP;
500500 }
501501 template
506506 BasicBlock *InsertAtEnd) {
507507 GetElementPtrInst *GEP = Create(Ptr, IdxBegin, IdxEnd,
508508 NameStr, InsertAtEnd);
509 cast(GEP)->setIsInBounds(true);
509 GEP->setIsInBounds(true);
510510 return GEP;
511511 }
512512 static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
513513 const Twine &NameStr = "",
514514 Instruction *InsertBefore = 0) {
515515 GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertBefore);
516 cast(GEP)->setIsInBounds(true);
516 GEP->setIsInBounds(true);
517517 return GEP;
518518 }
519519 static GetElementPtrInst *CreateInBounds(Value *Ptr, Value *Idx,
520520 const Twine &NameStr,
521521 BasicBlock *InsertAtEnd) {
522522 GetElementPtrInst *GEP = Create(Ptr, Idx, NameStr, InsertAtEnd);
523 cast(GEP)->setIsInBounds(true);
523 GEP->setIsInBounds(true);
524524 return GEP;
525525 }
526526
600600 /// constant integers. If so, the result pointer and the first operand have
601601 /// a constant offset between them.
602602 bool hasAllConstantIndices() const;
603
604 /// setIsInBounds - Set or clear the inbounds flag on this GEP instruction.
605 /// See LangRef.html for the meaning of inbounds on a getelementptr.
606 void setIsInBounds(bool);
603607
604608 // Methods for support type inquiry through isa, cast, and dyn_cast:
605609 static inline bool classof(const GetElementPtrInst *) { return true; }
2020 namespace llvm {
2121
2222 class GetElementPtrInst;
23 class BinaryOperator;
24 class ConstantExpr;
2325
2426 /// Operator - This is a utility class that provides an abstraction for the
2527 /// common functionality between Instructions and ConstantExprs.
6668 /// despite that operator having the potential for overflow.
6769 ///
6870 class OverflowingBinaryOperator : public Operator {
71 public:
72 enum {
73 NoUnsignedWrap = (1 << 0),
74 NoSignedWrap = (1 << 1)
75 };
76
77 private:
6978 ~OverflowingBinaryOperator(); // do not implement
79
80 friend class BinaryOperator;
81 friend class ConstantExpr;
82 void setHasNoUnsignedWrap(bool B) {
83 SubclassOptionalData =
84 (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
85 }
86 void setHasNoSignedWrap(bool B) {
87 SubclassOptionalData =
88 (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
89 }
90
7091 public:
7192 /// hasNoUnsignedWrap - Test whether this operation is known to never
7293 /// undergo unsigned overflow, aka the nuw property.
7394 bool hasNoUnsignedWrap() const {
74 return SubclassOptionalData & (1 << 0);
75 }
76 void setHasNoUnsignedWrap(bool B) {
77 SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
95 return SubclassOptionalData & NoUnsignedWrap;
7896 }
7997
8098 /// hasNoSignedWrap - Test whether this operation is known to never
8199 /// undergo signed overflow, aka the nsw property.
82100 bool hasNoSignedWrap() const {
83 return SubclassOptionalData & (1 << 1);
84 }
85 void setHasNoSignedWrap(bool B) {
86 SubclassOptionalData = (SubclassOptionalData & ~(1 << 1)) | (B << 1);
101 return SubclassOptionalData & NoSignedWrap;
87102 }
88103
89104 static inline bool classof(const OverflowingBinaryOperator *) { return true; }
160175 /// SDivOperator - An Operator with opcode Instruction::SDiv.
161176 ///
162177 class SDivOperator : public Operator {
178 public:
179 enum {
180 IsExact = (1 << 0)
181 };
182
183 private:
163184 ~SDivOperator(); // do not implement
185
186 friend class BinaryOperator;
187 friend class ConstantExpr;
188 void setIsExact(bool B) {
189 SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
190 }
191
164192 public:
165193 /// isExact - Test whether this division is known to be exact, with
166194 /// zero remainder.
167195 bool isExact() const {
168 return SubclassOptionalData & (1 << 0);
169 }
170 void setIsExact(bool B) {
171 SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
196 return SubclassOptionalData & IsExact;
172197 }
173198
174199 // Methods for support type inquiry through isa, cast, and dyn_cast:
186211 };
187212
188213 class GEPOperator : public Operator {
214 enum {
215 IsInBounds = (1 << 0)
216 };
217
189218 ~GEPOperator(); // do not implement
219
220 friend class GetElementPtrInst;
221 friend class ConstantExpr;
222 void setIsInBounds(bool B) {
223 SubclassOptionalData =
224 (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
225 }
226
190227 public:
191228 /// isInBounds - Test whether this is an inbounds GEP, as defined
192229 /// by LangRef.html.
193230 bool isInBounds() const {
194 return SubclassOptionalData & (1 << 0);
195 }
196 void setIsInBounds(bool B) {
197 SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0);
231 return SubclassOptionalData & IsInBounds;
198232 }
199233
200234 inline op_iterator idx_begin() { return op_begin()+1; }
144144 // uncheckedReplaceAllUsesWith - Just like replaceAllUsesWith but dangerous.
145145 // Only use when in type resolution situations!
146146 void uncheckedReplaceAllUsesWith(Value *V);
147
148 /// clearOptionalData - Clear any optional optimization data from this Value.
149 /// Transformation passes must call this method whenever changing the IR
150 /// in a way that would affect the values produced by this Value, unless
151 /// it takes special care to ensure correctness in some other way.
152 void clearOptionalData() { SubclassOptionalData = 0; }
153147
154148 //----------------------------------------------------------------------
155149 // Methods for handling the chain of uses of this Value.
239233 return SubclassID;
240234 }
241235
236 /// getRawSubclassOptionalData - Return the raw optional flags value
237 /// contained in this value. This should only be used when testing two
238 /// Values for equivalence.
239 unsigned getRawSubclassOptionalData() const {
240 return SubclassOptionalData;
241 }
242
242243 /// hasSameSubclassOptionalData - Test whether the optional flags contained
243244 /// in this value are equal to the optional flags in the given value.
244245 bool hasSameSubclassOptionalData(const Value *V) const {
20942094 if (!Val0->getType()->isIntOrIntVector() &&
20952095 !Val0->getType()->isFPOrFPVector())
20962096 return Error(ID.Loc,"constexpr requires integer, fp, or vector operands");
2097 Constant *C = ConstantExpr::get(Opc, Val0, Val1);
2098 if (NUW)
2099 cast(C)->setHasNoUnsignedWrap(true);
2100 if (NSW)
2101 cast(C)->setHasNoSignedWrap(true);
2102 if (Exact)
2103 cast(C)->setIsExact(true);
2097 unsigned Flags = 0;
2098 if (NUW) Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
2099 if (NSW) Flags |= OverflowingBinaryOperator::NoSignedWrap;
2100 if (Exact) Flags |= SDivOperator::IsExact;
2101 Constant *C = ConstantExpr::get(Opc, Val0, Val1, Flags);
21042102 ID.ConstantVal = C;
21052103 ID.Kind = ValID::t_Constant;
21062104 return false;
21562154 (Value**)(Elts.data() + 1),
21572155 Elts.size() - 1))
21582156 return Error(ID.Loc, "invalid indices for getelementptr");
2159 ID.ConstantVal = ConstantExpr::getGetElementPtr(Elts[0],
2160 Elts.data() + 1, Elts.size() - 1);
2161 if (InBounds)
2162 cast(ID.ConstantVal)->setIsInBounds(true);
2157 ID.ConstantVal = InBounds ?
2158 ConstantExpr::getInBoundsGetElementPtr(Elts[0],
2159 Elts.data() + 1,
2160 Elts.size() - 1) :
2161 ConstantExpr::getGetElementPtr(Elts[0],
2162 Elts.data() + 1, Elts.size() - 1);
21632163 } else if (Opc == Instruction::Select) {
21642164 if (Elts.size() != 3)
21652165 return Error(ID.Loc, "expected three operands to select");
26802680 return Error(ModifierLoc, "nsw only applies to integer operations");
26812681 }
26822682 if (NUW)
2683 cast<OverflowingBinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
2683 cast<BinaryOperator>(Inst)->setHasNoUnsignedWrap(true);
26842684 if (NSW)
2685 cast<OverflowingBinaryOperator>(Inst)->setHasNoSignedWrap(true);
2685 cast<BinaryOperator>(Inst)->setHasNoSignedWrap(true);
26862686 }
26872687 return Result;
26882688 }
26972697 bool Result = ParseArithmetic(Inst, PFS, KeywordVal, 1);
26982698 if (!Result)
26992699 if (Exact)
2700 cast<SDivOperator>(Inst)->setIsExact(true);
2700 cast<BinaryOperator>(Inst)->setIsExact(true);
27012701 return Result;
27022702 }
27032703
35003500 return Error(Loc, "invalid getelementptr indices");
35013501 Inst = GetElementPtrInst::Create(Ptr, Indices.begin(), Indices.end());
35023502 if (InBounds)
3503 castEPOperator>(Inst)->setIsInBounds(true);
3503 castetElementPtrInst>(Inst)->setIsInBounds(true);
35043504 return false;
35053505 }
35063506
882882 return false;
883883 }
884884
885 static void SetOptimizationFlags(Value *V, uint64_t Flags) {
886 if (OverflowingBinaryOperator *OBO =
887 dyn_cast(V)) {
888 if (Flags & (1 << bitc::OBO_NO_SIGNED_WRAP))
889 OBO->setHasNoSignedWrap(true);
890 if (Flags & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
891 OBO->setHasNoUnsignedWrap(true);
892 } else if (SDivOperator *Div = dyn_cast(V)) {
893 if (Flags & (1 << bitc::SDIV_EXACT))
894 Div->setIsExact(true);
895 }
896 }
897
898885 bool BitcodeReader::ParseConstants() {
899886 if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID))
900887 return Error("Malformed block record");
10461033 } else {
10471034 Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy);
10481035 Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy);
1049 V = ConstantExpr::get(Opc, LHS, RHS);
1050 }
1051 if (Record.size() >= 4)
1052 SetOptimizationFlags(V, Record[3]);
1036 unsigned Flags = 0;
1037 if (Record.size() >= 4) {
1038 if (Opc == Instruction::Add ||
1039 Opc == Instruction::Sub ||
1040 Opc == Instruction::Mul) {
1041 if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
1042 Flags |= OverflowingBinaryOperator::NoSignedWrap;
1043 if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
1044 Flags |= OverflowingBinaryOperator::NoUnsignedWrap;
1045 } else if (Opc == Instruction::SDiv) {
1046 if (Record[3] & (1 << bitc::SDIV_EXACT))
1047 Flags |= SDivOperator::IsExact;
1048 }
1049 }
1050 V = ConstantExpr::get(Opc, LHS, RHS, Flags);
1051 }
10531052 break;
10541053 }
10551054 case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval]
10741073 if (!ElTy) return Error("Invalid CE_GEP record");
10751074 Elts.push_back(ValueList.getConstantFwdRef(Record[i+1], ElTy));
10761075 }
1077 V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1],
1078 Elts.size()-1);
10791076 if (BitCode == bitc::CST_CODE_CE_INBOUNDS_GEP)
1080 cast(V)->setIsInBounds(true);
1077 V = ConstantExpr::getInBoundsGetElementPtr(Elts[0], &Elts[1],
1078 Elts.size()-1);
1079 else
1080 V = ConstantExpr::getGetElementPtr(Elts[0], &Elts[1],
1081 Elts.size()-1);
10811082 break;
10821083 }
10831084 case bitc::CST_CODE_CE_SELECT: // CE_SELECT: [opval#, opval#, opval#]
16091610 int Opc = GetDecodedBinaryOpcode(Record[OpNum++], LHS->getType());
16101611 if (Opc == -1) return Error("Invalid BINOP record");
16111612 I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS);
1612 if (OpNum < Record.size())
1613 SetOptimizationFlags(I, Record[3]);
1613 if (OpNum < Record.size()) {
1614 if (Opc == Instruction::Add ||
1615 Opc == Instruction::Sub ||
1616 Opc == Instruction::Mul) {
1617 if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP))
1618 cast(I)->setHasNoSignedWrap(true);
1619 if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP))
1620 cast(I)->setHasNoUnsignedWrap(true);
1621 } else if (Opc == Instruction::SDiv) {
1622 if (Record[3] & (1 << bitc::SDIV_EXACT))
1623 cast(I)->setIsExact(true);
1624 }
1625 }
16141626 break;
16151627 }
16161628 case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc]
16441656
16451657 I = GetElementPtrInst::Create(BasePtr, GEPIdx.begin(), GEPIdx.end());
16461658 if (BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP)
1647 castEPOperator>(I)->setIsInBounds(true);
1659 castetElementPtrInst>(I)->setIsInBounds(true);
16481660 break;
16491661 }
16501662
80858085 // If we were able to index down into an element, create the GEP
80868086 // and bitcast the result. This eliminates one bitcast, potentially
80878087 // two.
8088 Value *NGEP = Builder->CreateGEP(OrigBase, NewIndices.begin(),
8089 NewIndices.end());
8088 Value *NGEP = cast(GEP)->isInBounds() ?
8089 Builder->CreateInBoundsGEP(OrigBase,
8090 NewIndices.begin(), NewIndices.end()) :
8091 Builder->CreateGEP(OrigBase, NewIndices.begin(), NewIndices.end());
80908092 NGEP->takeName(GEP);
8091 if (isa(NGEP) && cast(GEP)->isInBounds())
8092 cast(NGEP)->setIsInBounds(true);
80938093
80948094 if (isa(CI))
80958095 return new BitCastInst(NGEP, CI.getType());
88048804 // If we found a path from the src to dest, create the getelementptr now.
88058805 if (SrcElTy == DstElTy) {
88068806 SmallVector Idxs(NumZeros+1, ZeroUInt);
8807 Instruction *GEP = GetElementPtrInst::Create(Src,
8808 Idxs.begin(), Idxs.end(), "",
8809 ((Instruction*) NULL));
8810 cast(GEP)->setIsInBounds(true);
8811 return GEP;
8807 return GetElementPtrInst::CreateInBounds(Src, Idxs.begin(), Idxs.end(), "",
8808 ((Instruction*) NULL));
88128809 }
88138810 }
88148811
1048010477 }
1048110478
1048210479 Value *Base = FixedOperands[0];
10483 GetElementPtrInst *GEP =
10480 return cast(FirstInst)->isInBounds() ?
10481 GetElementPtrInst::CreateInBounds(Base, FixedOperands.begin()+1,
10482 FixedOperands.end()) :
1048410483 GetElementPtrInst::Create(Base, FixedOperands.begin()+1,
1048510484 FixedOperands.end());
10486 if (cast(FirstInst)->isInBounds())
10487 cast(GEP)->setIsInBounds(true);
10488 return GEP;
1048910485 }
1049010486
1049110487
1088810884 Indices.append(GEP.idx_begin()+1, GEP.idx_end());
1088910885 }
1089010886
10891 if (!Indices.empty()) {
10892 GetElementPtrInst *NewGEP =
10887 if (!Indices.empty())
10888 return (cast(&GEP)->isInBounds() &&
10889 Src->isInBounds()) ?
10890 GetElementPtrInst::CreateInBounds(Src->getOperand(0), Indices.begin(),
10891 Indices.end(), GEP.getName()) :
1089310892 GetElementPtrInst::Create(Src->getOperand(0), Indices.begin(),
1089410893 Indices.end(), GEP.getName());
10895 if (cast(&GEP)->isInBounds() && Src->isInBounds())
10896 cast(NewGEP)->setIsInBounds(true);
10897 return NewGEP;
10898 }
1089910894 }
1090010895
1090110896 // Handle gep(bitcast x) and gep(gep x, 0, 0, 0).
1092510920 if (CATy->getElementType() == XTy->getElementType()) {
1092610921 // -> GEP i8* X, ...
1092710922 SmallVector Indices(GEP.idx_begin()+1, GEP.idx_end());
10928 GetElementPtrInst *NewGEP =
10923 return cast(&GEP)->isInBounds() ?
10924 GetElementPtrInst::CreateInBounds(X, Indices.begin(), Indices.end(),
10925 GEP.getName()) :
1092910926 GetElementPtrInst::Create(X, Indices.begin(), Indices.end(),
1093010927 GEP.getName());
10931 if (cast(&GEP)->isInBounds())
10932 cast(NewGEP)->setIsInBounds(true);
10933 return NewGEP;
1093410928 }
1093510929
1093610930 if (const ArrayType *XATy = dyn_cast(XTy->getElementType())){
1095810952 Value *Idx[2];
1095910953 Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
1096010954 Idx[1] = GEP.getOperand(1);
10961 Value *NewGEP =
10955 Value *NewGEP = cast(&GEP)->isInBounds() ?
10956 Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
1096210957 Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
10963 if (cast(&GEP)->isInBounds())
10964 cast(NewGEP)->setIsInBounds(true);
1096510958 // V and GEP are both pointer types --> BitCast
1096610959 return new BitCastInst(NewGEP, GEP.getType());
1096710960 }
1101811011 Value *Idx[2];
1101911012 Idx[0] = Constant::getNullValue(Type::getInt32Ty(*Context));
1102011013 Idx[1] = NewIdx;
11021 Value *NewGEP = Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
11022 if (cast(&GEP)->isInBounds())
11023 cast(NewGEP)->setIsInBounds(true);
11014 Value *NewGEP = cast(&GEP)->isInBounds() ?
11015 Builder->CreateInBoundsGEP(X, Idx, Idx + 2, GEP.getName()) :
11016 Builder->CreateGEP(X, Idx, Idx + 2, GEP.getName());
1102411017 // The NewGEP must be pointer typed, so must the old one -> BitCast
1102511018 return new BitCastInst(NewGEP, GEP.getType());
1102611019 }
1106811061 const Type *InTy =
1106911062 cast(BCI->getOperand(0)->getType())->getElementType();
1107011063 if (FindElementAtOffset(InTy, Offset, NewIndices, TD, Context)) {
11071 Value *NGEP = Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
11072 NewIndices.end());
11073 if (cast(&GEP)->isInBounds())
11074 cast(NGEP)->setIsInBounds(true);
11064 Value *NGEP = cast(&GEP)->isInBounds() ?
11065 Builder->CreateInBoundsGEP(BCI->getOperand(0), NewIndices.begin(),
11066 NewIndices.end()) :
11067 Builder->CreateGEP(BCI->getOperand(0), NewIndices.begin(),
11068 NewIndices.end());
1107511069
1107611070 if (NGEP->getType() == GEP.getType())
1107711071 return ReplaceInstUsesWith(GEP, NGEP);
1111411108 Value *Idx[2];
1111511109 Idx[0] = NullIdx;
1111611110 Idx[1] = NullIdx;
11117 Value *V = GetElementPtrInst::Create(New, Idx, Idx + 2,
11118 New->getName()+".sub", It);
11119 cast(V)->setIsInBounds(true);
11111 Value *V = GetElementPtrInst::CreateInBounds(New, Idx, Idx + 2,
11112 New->getName()+".sub", It);
1112011113
1112111114 // Now make everything use the getelementptr instead of the original
1112211115 // allocation.
1148511478
1148611479 // SIOp0 is a pointer to aggregate and this is a store to the first field,
1148711480 // emit a GEP to index into its first field.
11488 if (!NewGEPIndices.empty()) {
11489 CastOp = IC.Builder->CreateGEP(CastOp, NewGEPIndices.begin(),
11490 NewGEPIndices.end());
11491 cast(CastOp)->setIsInBounds(true);
11492 }
11481 if (!NewGEPIndices.empty())
11482 CastOp = IC.Builder->CreateInBoundsGEP(CastOp, NewGEPIndices.begin(),
11483 NewGEPIndices.end());
1149311484
1149411485 NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
1149511486 SIOp0->getName()+".c");
1215912150 PointerType::get(EI.getType(), AS),
1216012151 I->getOperand(0)->getName());
1216112152 Value *GEP =
12162 Builder->CreateGEP(Ptr, EI.getOperand(1), I->getName()+".gep");
12163 cast(GEP)->setIsInBounds(true);
12153 Builder->CreateInBoundsGEP(Ptr, EI.getOperand(1), I->getName()+".gep");
1216412154
1216512155 LoadInst *Load = Builder->CreateLoad(GEP, "tmp");
1216612156
631631 }
632632
633633 Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
634 Constant *C = getAdd(C1, C2);
635 // Set nsw attribute, assuming constant folding didn't eliminate the
636 // Add.
637 if (AddOperator *Add = dyn_cast(C))
638 Add->setHasNoSignedWrap(true);
639 return C;
634 return getTy(C1->getType(), Instruction::Add, C1, C2,
635 OverflowingBinaryOperator::NoSignedWrap);
640636 }
641637
642638 Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
643 Constant *C = getSDiv(C1, C2);
644 // Set exact attribute, assuming constant folding didn't eliminate the
645 // SDiv.
646 if (SDivOperator *SDiv = dyn_cast(C))
647 SDiv->setIsExact(true);
648 return C;
639 return getTy(C1->getType(), Instruction::SDiv, C1, C2,
640 SDivOperator::IsExact);
649641 }
650642
651643 // Utility function for determining if a ConstantExpr is a CastOp or not. This
728720 for (unsigned i = 1, e = getNumOperands(); i != e; ++i)
729721 Ops[i-1] = getOperand(i);
730722 if (OpNo == 0)
731 return ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
723 return cast(this)->isInBounds() ?
724 ConstantExpr::getInBoundsGetElementPtr(Op, &Ops[0], Ops.size()) :
725 ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
732726 Ops[OpNo-1] = Op;
733 return ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size());
727 return cast(this)->isInBounds() ?
728 ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) :
729 ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size());
734730 }
735731 default:
736732 assert(getNumOperands() == 2 && "Must be binary operator?");
737733 Op0 = (OpNo == 0) ? Op : getOperand(0);
738734 Op1 = (OpNo == 1) ? Op : getOperand(1);
739 return ConstantExpr::get(getOpcode(), Op0, Op1);
735 return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassData);
740736 }
741737 }
742738
778774 case Instruction::ShuffleVector:
779775 return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
780776 case Instruction::GetElementPtr:
781 return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
777 return cast(this)->isInBounds() ?
778 ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], NumOps-1) :
779 ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1);
782780 case Instruction::ICmp:
783781 case Instruction::FCmp:
784782 return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
785783 default:
786784 assert(getNumOperands() == 2 && "Must be binary operator?");
787 return ConstantExpr::get(getOpcode(), Ops[0], Ops[1]);
785 return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData);
788786 }
789787 }
790788
10301028 Operands.reserve(CE->getNumOperands());
10311029 for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i)
10321030 Operands.push_back(cast(CE->getOperand(i)));
1033 return ExprMapKeyType(CE->getOpcode(), Operands,
1031 return ExprMapKeyType(CE->getOpcode(), Operands,
10341032 CE->isCompare() ? CE->getPredicate() : 0,
1033 CE->getRawSubclassOptionalData(),
10351034 CE->hasIndices() ?
10361035 CE->getIndices() : SmallVector());
10371036 }
12791278 }
12801279
12811280 Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
1282 Constant *C1, Constant *C2) {
1281 Constant *C1, Constant *C2,
1282 unsigned Flags) {
12831283 // Check the operands for consistency first
12841284 assert(Opcode >= Instruction::BinaryOpsBegin &&
12851285 Opcode < Instruction::BinaryOpsEnd &&
12931293 return FC; // Fold a few common cases...
12941294
12951295 std::vector argVec(1, C1); argVec.push_back(C2);
1296 ExprMapKeyType Key(Opcode, argVec);
1296 ExprMapKeyType Key(Opcode, argVec, 0, Flags);
12971297
12981298 LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
12991299
13211321 }
13221322 }
13231323
1324 Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
1324 Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
1325 unsigned Flags) {
13251326 // API compatibility: Adjust integer opcodes to floating-point opcodes.
13261327 if (C1->getType()->isFPOrFPVector()) {
13271328 if (Opcode == Instruction::Add) Opcode = Instruction::FAdd;
13861387 }
13871388 #endif
13881389
1389 return getTy(C1->getType(), Opcode, C1, C2);
1390 return getTy(C1->getType(), Opcode, C1, C2, Flags);
13901391 }
13911392
13921393 Constant* ConstantExpr::getSizeOf(const Type* Ty) {
14801481 return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
14811482 }
14821483
1484 Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy,
1485 Constant *C,
1486 Value* const *Idxs,
1487 unsigned NumIdx) {
1488 assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs,
1489 Idxs+NumIdx) ==
1490 cast(ReqTy)->getElementType() &&
1491 "GEP indices invalid!");
1492
1493 if (Constant *FC = ConstantFoldGetElementPtr(
1494 ReqTy->getContext(), C, (Constant**)Idxs, NumIdx))
1495 return FC; // Fold a few common cases...
1496
1497 assert(isa(C->getType()) &&
1498 "Non-pointer type for constant GetElementPtr expression");
1499 // Look up the constant in the table first to ensure uniqueness
1500 std::vector ArgVec;
1501 ArgVec.reserve(NumIdx+1);
1502 ArgVec.push_back(C);
1503 for (unsigned i = 0; i != NumIdx; ++i)
1504 ArgVec.push_back(cast(Idxs[i]));
1505 const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0,
1506 GEPOperator::IsInBounds);
1507
1508 LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
1509
1510 // Implicitly locked.
1511 return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
1512 }
1513
14831514 Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs,
14841515 unsigned NumIdx) {
14851516 // Get the result type of the getelementptr!
14931524 Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C,
14941525 Value* const *Idxs,
14951526 unsigned NumIdx) {
1496 Constant *Result = getGetElementPtr(C, Idxs, NumIdx);
1497 // Set in bounds attribute, assuming constant folding didn't eliminate the
1498 // GEP.
1499 if (GEPOperator *GEP = dyn_cast(Result))
1500 GEP->setIsInBounds(true);
1501 return Result;
1527 // Get the result type of the getelementptr!
1528 const Type *Ty =
1529 GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx);
1530 assert(Ty && "GEP indices invalid!");
1531 unsigned As = cast(C->getType())->getAddressSpace();
1532 return getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx);
15021533 }
15031534
15041535 Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs,
21032134 Constant *C2 = getOperand(1);
21042135 if (C1 == From) C1 = To;
21052136 if (C2 == From) C2 = To;
2106 Replacement = ConstantExpr::get(getOpcode(), C1, C2);
2137 Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData);
21072138 } else {
21082139 llvm_unreachable("Unknown ConstantExpr type!");
21092140 return;
5252 void *operator new(size_t s) {
5353 return User::operator new(s, 2);
5454 }
55 BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2)
55 BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2,
56 unsigned Flags)
5657 : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) {
5758 Op<0>() = C1;
5859 Op<1>() = C2;
60 SubclassOptionalData = Flags;
5961 }
6062 /// Transparently provide more efficient getOperand methods.
6163 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
205207 public:
206208 static GetElementPtrConstantExpr *Create(Constant *C,
207209 const std::vector&IdxList,
208 const Type *DestTy) {
209 return
210 const Type *DestTy,
211 unsigned Flags) {
212 GetElementPtrConstantExpr *Result =
210213 new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy);
214 Result->SubclassOptionalData = Flags;
215 return Result;
211216 }
212217 /// Transparently provide more efficient getOperand methods.
213218 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
290295
291296 ExprMapKeyType(unsigned opc,
292297 const std::vector &ops,
293 unsigned short pred = 0,
298 unsigned short flags = 0,
299 unsigned short optionalflags = 0,
294300 const IndexList &inds = IndexList())
295 : opcode(opc), predicate(pred), operands(ops), indices(inds) {}
296 uint16_t opcode;
297 uint16_t predicate;
301 : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags),
302 operands(ops), indices(inds) {}
303 uint8_t opcode;
304 uint8_t subclassoptionaldata;
305 uint16_t subclassdata;
298306 std::vector operands;
299307 IndexList indices;
300308 bool operator==(const ExprMapKeyType& that) const {
301309 return this->opcode == that.opcode &&
302 this->predicate == that.predicate &&
310 this->subclassdata == that.subclassdata &&
311 this->subclassoptionaldata == that.subclassoptionaldata &&
303312 this->operands == that.operands &&
304313 this->indices == that.indices;
305314 }
306315 bool operator<(const ExprMapKeyType & that) const {
307 return this->opcode < that.opcode ||
308 (this->opcode == that.opcode && this->predicate < that.predicate) ||
309 (this->opcode == that.opcode && this->predicate == that.predicate &&
310 this->operands < that.operands) ||
311 (this->opcode == that.opcode && this->predicate == that.predicate &&
312 this->operands == that.operands && this->indices < that.indices);
316 if (this->opcode != that.opcode) return this->opcode < that.opcode;
317 if (this->operands != that.operands) return this->operands < that.operands;
318 if (this->subclassdata != that.subclassdata)
319 return this->subclassdata < that.subclassdata;
320 if (this->subclassoptionaldata != that.subclassoptionaldata)
321 return this->subclassoptionaldata < that.subclassoptionaldata;
322 if (this->indices != that.indices) return this->indices < that.indices;
323 return false;
313324 }
314325
315326 bool operator!=(const ExprMapKeyType& that) const {
353364 return new UnaryConstantExpr(V.opcode, V.operands[0], Ty);
354365 if ((V.opcode >= Instruction::BinaryOpsBegin &&
355366 V.opcode < Instruction::BinaryOpsEnd))
356 return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]);
367 return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1],
368 V.subclassoptionaldata);
357369 if (V.opcode == Instruction::Select)
358370 return new SelectConstantExpr(V.operands[0], V.operands[1],
359371 V.operands[2]);
372384 return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty);
373385 if (V.opcode == Instruction::GetElementPtr) {
374386 std::vector IdxList(V.operands.begin()+1, V.operands.end());
375 return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty);
387 return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty,
388 V.subclassoptionaldata);
376389 }
377390
378391 // The compare instructions are weird. We have to encode the predicate
379392 // value and it is combined with the instruction opcode by multiplying
380393 // the opcode by one hundred. We must decode this to get the predicate.
381394 if (V.opcode == Instruction::ICmp)
382 return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate,
395 return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata,
383396 V.operands[0], V.operands[1]);
384397 if (V.opcode == Instruction::FCmp)
385 return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate,
398 return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata,
386399 V.operands[0], V.operands[1]);
387400 llvm_unreachable("Invalid ConstantExpr!");
388401 return 0;
11701170 return true;
11711171 }
11721172
1173 void GetElementPtrInst::setIsInBounds(bool B) {
1174 cast(this)->setIsInBounds(B);
1175 }
11731176
11741177 //===----------------------------------------------------------------------===//
11751178 // ExtractElementInst Implementation
17131716 return true; // Can't commute operands
17141717 Op<0>().swap(Op<1>());
17151718 return false;
1719 }
1720
1721 void BinaryOperator::setHasNoUnsignedWrap(bool b) {
1722 cast(this)->setHasNoUnsignedWrap(b);
1723 }
1724
1725 void BinaryOperator::setHasNoSignedWrap(bool b) {
1726 cast(this)->setHasNoSignedWrap(b);
1727 }
1728
1729 void BinaryOperator::setIsExact(bool b) {
1730 cast(this)->setIsExact(b);
17161731 }
17171732
17181733 //===----------------------------------------------------------------------===//
+0
-28
test/Assembler/flags-plain.ll less more
None ; RUN: llvm-as < %s | llvm-dis | FileCheck %s
1
2 @addr = external global i64
3
4 define i64 @add_plain_ce() {
5 ; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
6 ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
7 }
8
9 define i64 @sub_plain_ce() {
10 ; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
11 ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
12 }
13
14 define i64 @mul_plain_ce() {
15 ; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
16 ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
17 }
18
19 define i64 @sdiv_plain_ce() {
20 ; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
21 ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
22 }
23
24 define i64* @gep_plain_ce() {
25 ; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
26 ret i64* getelementptr (i64* @addr, i64 171)
27 }
+0
-18
test/Assembler/flags-reversed.ll less more
None ; RUN: llvm-as < %s | llvm-dis | FileCheck %s
1
2 @addr = external global i64
3
4 define i64 @add_both_reversed_ce() {
5 ; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
6 ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
7 }
8
9 define i64 @sub_both_reversed_ce() {
10 ; CHECK: ret i64 sub nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
11 ret i64 sub nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
12 }
13
14 define i64 @mul_both_reversed_ce() {
15 ; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
16 ret i64 mul nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
17 }
+0
-18
test/Assembler/flags-signed.ll less more
None ; RUN: llvm-as < %s | llvm-dis | FileCheck %s
1
2 @addr = external global i64
3
4 define i64 @add_signed_ce() {
5 ; CHECK: ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
6 ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
7 }
8
9 define i64 @sub_signed_ce() {
10 ; CHECK: ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
11 ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
12 }
13
14 define i64 @mul_signed_ce() {
15 ; CHECK: ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
16 ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
17 }
+0
-18
test/Assembler/flags-unsigned.ll less more
None ; RUN: llvm-as < %s | llvm-dis | FileCheck %s
1
2 @addr = external global i64
3
4 define i64 @add_unsigned_ce() {
5 ; CHECK: ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
6 ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
7 }
8
9 define i64 @sub_unsigned_ce() {
10 ; CHECK: ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
11 ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
12 }
13
14 define i64 @mul_unsigned_ce() {
15 ; CHECK: ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
16 ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
17 }
140140 ret i64* getelementptr inbounds (i64* @addr, i64 171)
141141 }
142142
143
143 define i64 @add_plain_ce() {
144 ; CHECK: ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
145 ret i64 add (i64 ptrtoint (i64* @addr to i64), i64 91)
146 }
147
148 define i64 @sub_plain_ce() {
149 ; CHECK: ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
150 ret i64 sub (i64 ptrtoint (i64* @addr to i64), i64 91)
151 }
152
153 define i64 @mul_plain_ce() {
154 ; CHECK: ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
155 ret i64 mul (i64 ptrtoint (i64* @addr to i64), i64 91)
156 }
157
158 define i64 @sdiv_plain_ce() {
159 ; CHECK: ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
160 ret i64 sdiv (i64 ptrtoint (i64* @addr to i64), i64 91)
161 }
162
163 define i64* @gep_plain_ce() {
164 ; CHECK: ret i64* getelementptr (i64* @addr, i64 171)
165 ret i64* getelementptr (i64* @addr, i64 171)
166 }
167
168 define i64 @add_both_reversed_ce() {
169 ; CHECK: ret i64 add nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
170 ret i64 add nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
171 }
172
173 define i64 @sub_both_reversed_ce() {
174 ; CHECK: ret i64 sub nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
175 ret i64 sub nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
176 }
177
178 define i64 @mul_both_reversed_ce() {
179 ; CHECK: ret i64 mul nuw nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
180 ret i64 mul nsw nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
181 }
182
183 define i64 @add_signed_ce() {
184 ; CHECK: ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
185 ret i64 add nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
186 }
187
188 define i64 @sub_signed_ce() {
189 ; CHECK: ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
190 ret i64 sub nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
191 }
192
193 define i64 @mul_signed_ce() {
194 ; CHECK: ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
195 ret i64 mul nsw (i64 ptrtoint (i64* @addr to i64), i64 91)
196 }
197
198 define i64 @add_unsigned_ce() {
199 ; CHECK: ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
200 ret i64 add nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
201 }
202
203 define i64 @sub_unsigned_ce() {
204 ; CHECK: ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
205 ret i64 sub nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
206 }
207
208 define i64 @mul_unsigned_ce() {
209 ; CHECK: ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
210 ret i64 mul nuw (i64 ptrtoint (i64* @addr to i64), i64 91)
211 }