mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-02-14 14:56:47 +00:00
[C API] Add getters and setters for NUW, NSW, and Exact
This partially addresses Bug 42692; see discussion there. Adds C API getters and setters for the NUW, NSW, and Exact flags on various instructions. Patch by Craig Disselkoen. Thanks! Differential Revision: https://reviews.llvm.org/D89252
This commit is contained in:
parent
16946466fd
commit
de9b6aa341
@ -3913,6 +3913,13 @@ LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
|
||||
LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
|
||||
LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name);
|
||||
|
||||
LLVMBool LLVMGetNUW(LLVMValueRef ArithInst);
|
||||
void LLVMSetNUW(LLVMValueRef ArithInst, LLVMBool HasNUW);
|
||||
LLVMBool LLVMGetNSW(LLVMValueRef ArithInst);
|
||||
void LLVMSetNSW(LLVMValueRef ArithInst, LLVMBool HasNSW);
|
||||
LLVMBool LLVMGetExact(LLVMValueRef DivOrShrInst);
|
||||
void LLVMSetExact(LLVMValueRef DivOrShrInst, LLVMBool IsExact);
|
||||
|
||||
/* Memory */
|
||||
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
|
||||
LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty,
|
||||
|
@ -3444,6 +3444,36 @@ LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
|
||||
return wrap(unwrap(B)->CreateNot(unwrap(V), Name));
|
||||
}
|
||||
|
||||
LLVMBool LLVMGetNUW(LLVMValueRef ArithInst) {
|
||||
Value *P = unwrap<Value>(ArithInst);
|
||||
return cast<Instruction>(P)->hasNoUnsignedWrap();
|
||||
}
|
||||
|
||||
void LLVMSetNUW(LLVMValueRef ArithInst, LLVMBool HasNUW) {
|
||||
Value *P = unwrap<Value>(ArithInst);
|
||||
cast<Instruction>(P)->setHasNoUnsignedWrap(HasNUW);
|
||||
}
|
||||
|
||||
LLVMBool LLVMGetNSW(LLVMValueRef ArithInst) {
|
||||
Value *P = unwrap<Value>(ArithInst);
|
||||
return cast<Instruction>(P)->hasNoSignedWrap();
|
||||
}
|
||||
|
||||
void LLVMSetNSW(LLVMValueRef ArithInst, LLVMBool HasNSW) {
|
||||
Value *P = unwrap<Value>(ArithInst);
|
||||
cast<Instruction>(P)->setHasNoSignedWrap(HasNSW);
|
||||
}
|
||||
|
||||
LLVMBool LLVMGetExact(LLVMValueRef DivOrShrInst) {
|
||||
Value *P = unwrap<Value>(DivOrShrInst);
|
||||
return cast<Instruction>(P)->isExact();
|
||||
}
|
||||
|
||||
void LLVMSetExact(LLVMValueRef DivOrShrInst, LLVMBool IsExact) {
|
||||
Value *P = unwrap<Value>(DivOrShrInst);
|
||||
cast<Instruction>(P)->setIsExact(IsExact);
|
||||
}
|
||||
|
||||
/*--.. Memory ..............................................................--*/
|
||||
|
||||
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
|
||||
|
@ -80,7 +80,17 @@ define i32 @iops(i32 %a, i32 %b) {
|
||||
%11 = and i32 %9, %10
|
||||
%12 = or i32 %2, %11
|
||||
%13 = xor i32 %12, %4
|
||||
ret i32 %13
|
||||
%14 = add nuw i32 %13, %a
|
||||
%15 = add nsw i32 %14, %b
|
||||
%16 = add nuw nsw i32 %15, %a
|
||||
%17 = shl nuw i32 %16, %a
|
||||
%18 = shl nsw i32 %17, %b
|
||||
%19 = shl nuw nsw i32 %18, %a
|
||||
%20 = udiv exact i32 %19, %1
|
||||
%21 = sdiv exact i32 %20, %2
|
||||
%22 = lshr exact i32 %21, %4
|
||||
%23 = ashr exact i32 %22, %14
|
||||
ret i32 %23
|
||||
}
|
||||
|
||||
define i32 @call() {
|
||||
|
@ -536,31 +536,47 @@ struct FunCloner {
|
||||
case LLVMAdd: {
|
||||
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
|
||||
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
|
||||
LLVMBool NUW = LLVMGetNUW(Src);
|
||||
LLVMBool NSW = LLVMGetNSW(Src);
|
||||
Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
|
||||
LLVMSetNUW(Dst, NUW);
|
||||
LLVMSetNSW(Dst, NSW);
|
||||
break;
|
||||
}
|
||||
case LLVMSub: {
|
||||
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
|
||||
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
|
||||
LLVMBool NUW = LLVMGetNUW(Src);
|
||||
LLVMBool NSW = LLVMGetNSW(Src);
|
||||
Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
|
||||
LLVMSetNUW(Dst, NUW);
|
||||
LLVMSetNSW(Dst, NSW);
|
||||
break;
|
||||
}
|
||||
case LLVMMul: {
|
||||
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
|
||||
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
|
||||
LLVMBool NUW = LLVMGetNUW(Src);
|
||||
LLVMBool NSW = LLVMGetNSW(Src);
|
||||
Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
|
||||
LLVMSetNUW(Dst, NUW);
|
||||
LLVMSetNSW(Dst, NSW);
|
||||
break;
|
||||
}
|
||||
case LLVMUDiv: {
|
||||
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
|
||||
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
|
||||
LLVMBool IsExact = LLVMGetExact(Src);
|
||||
Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
|
||||
LLVMSetExact(Dst, IsExact);
|
||||
break;
|
||||
}
|
||||
case LLVMSDiv: {
|
||||
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
|
||||
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
|
||||
LLVMBool IsExact = LLVMGetExact(Src);
|
||||
Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
|
||||
LLVMSetExact(Dst, IsExact);
|
||||
break;
|
||||
}
|
||||
case LLVMURem: {
|
||||
@ -578,19 +594,27 @@ struct FunCloner {
|
||||
case LLVMShl: {
|
||||
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
|
||||
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
|
||||
LLVMBool NUW = LLVMGetNUW(Src);
|
||||
LLVMBool NSW = LLVMGetNSW(Src);
|
||||
Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
|
||||
LLVMSetNUW(Dst, NUW);
|
||||
LLVMSetNSW(Dst, NSW);
|
||||
break;
|
||||
}
|
||||
case LLVMLShr: {
|
||||
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
|
||||
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
|
||||
LLVMBool IsExact = LLVMGetExact(Src);
|
||||
Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
|
||||
LLVMSetExact(Dst, IsExact);
|
||||
break;
|
||||
}
|
||||
case LLVMAShr: {
|
||||
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
|
||||
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
|
||||
LLVMBool IsExact = LLVMGetExact(Src);
|
||||
Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
|
||||
LLVMSetExact(Dst, IsExact);
|
||||
break;
|
||||
}
|
||||
case LLVMAnd: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user