Skip to content

Commit de9b6aa

Browse files
committed
[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
1 parent 1694646 commit de9b6aa

File tree

4 files changed

+72
-1
lines changed

4 files changed

+72
-1
lines changed

Diff for: llvm/include/llvm-c/Core.h

+7
Original file line numberDiff line numberDiff line change
@@ -3913,6 +3913,13 @@ LLVMValueRef LLVMBuildNUWNeg(LLVMBuilderRef B, LLVMValueRef V,
39133913
LLVMValueRef LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef V, const char *Name);
39143914
LLVMValueRef LLVMBuildNot(LLVMBuilderRef, LLVMValueRef V, const char *Name);
39153915

3916+
LLVMBool LLVMGetNUW(LLVMValueRef ArithInst);
3917+
void LLVMSetNUW(LLVMValueRef ArithInst, LLVMBool HasNUW);
3918+
LLVMBool LLVMGetNSW(LLVMValueRef ArithInst);
3919+
void LLVMSetNSW(LLVMValueRef ArithInst, LLVMBool HasNSW);
3920+
LLVMBool LLVMGetExact(LLVMValueRef DivOrShrInst);
3921+
void LLVMSetExact(LLVMValueRef DivOrShrInst, LLVMBool IsExact);
3922+
39163923
/* Memory */
39173924
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef Ty, const char *Name);
39183925
LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef Ty,

Diff for: llvm/lib/IR/Core.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -3444,6 +3444,36 @@ LLVMValueRef LLVMBuildNot(LLVMBuilderRef B, LLVMValueRef V, const char *Name) {
34443444
return wrap(unwrap(B)->CreateNot(unwrap(V), Name));
34453445
}
34463446

3447+
LLVMBool LLVMGetNUW(LLVMValueRef ArithInst) {
3448+
Value *P = unwrap<Value>(ArithInst);
3449+
return cast<Instruction>(P)->hasNoUnsignedWrap();
3450+
}
3451+
3452+
void LLVMSetNUW(LLVMValueRef ArithInst, LLVMBool HasNUW) {
3453+
Value *P = unwrap<Value>(ArithInst);
3454+
cast<Instruction>(P)->setHasNoUnsignedWrap(HasNUW);
3455+
}
3456+
3457+
LLVMBool LLVMGetNSW(LLVMValueRef ArithInst) {
3458+
Value *P = unwrap<Value>(ArithInst);
3459+
return cast<Instruction>(P)->hasNoSignedWrap();
3460+
}
3461+
3462+
void LLVMSetNSW(LLVMValueRef ArithInst, LLVMBool HasNSW) {
3463+
Value *P = unwrap<Value>(ArithInst);
3464+
cast<Instruction>(P)->setHasNoSignedWrap(HasNSW);
3465+
}
3466+
3467+
LLVMBool LLVMGetExact(LLVMValueRef DivOrShrInst) {
3468+
Value *P = unwrap<Value>(DivOrShrInst);
3469+
return cast<Instruction>(P)->isExact();
3470+
}
3471+
3472+
void LLVMSetExact(LLVMValueRef DivOrShrInst, LLVMBool IsExact) {
3473+
Value *P = unwrap<Value>(DivOrShrInst);
3474+
cast<Instruction>(P)->setIsExact(IsExact);
3475+
}
3476+
34473477
/*--.. Memory ..............................................................--*/
34483478

34493479
LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,

Diff for: llvm/test/Bindings/llvm-c/echo.ll

+11-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,17 @@ define i32 @iops(i32 %a, i32 %b) {
8080
%11 = and i32 %9, %10
8181
%12 = or i32 %2, %11
8282
%13 = xor i32 %12, %4
83-
ret i32 %13
83+
%14 = add nuw i32 %13, %a
84+
%15 = add nsw i32 %14, %b
85+
%16 = add nuw nsw i32 %15, %a
86+
%17 = shl nuw i32 %16, %a
87+
%18 = shl nsw i32 %17, %b
88+
%19 = shl nuw nsw i32 %18, %a
89+
%20 = udiv exact i32 %19, %1
90+
%21 = sdiv exact i32 %20, %2
91+
%22 = lshr exact i32 %21, %4
92+
%23 = ashr exact i32 %22, %14
93+
ret i32 %23
8494
}
8595

8696
define i32 @call() {

Diff for: llvm/tools/llvm-c-test/echo.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -536,31 +536,47 @@ struct FunCloner {
536536
case LLVMAdd: {
537537
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
538538
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
539+
LLVMBool NUW = LLVMGetNUW(Src);
540+
LLVMBool NSW = LLVMGetNSW(Src);
539541
Dst = LLVMBuildAdd(Builder, LHS, RHS, Name);
542+
LLVMSetNUW(Dst, NUW);
543+
LLVMSetNSW(Dst, NSW);
540544
break;
541545
}
542546
case LLVMSub: {
543547
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
544548
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
549+
LLVMBool NUW = LLVMGetNUW(Src);
550+
LLVMBool NSW = LLVMGetNSW(Src);
545551
Dst = LLVMBuildSub(Builder, LHS, RHS, Name);
552+
LLVMSetNUW(Dst, NUW);
553+
LLVMSetNSW(Dst, NSW);
546554
break;
547555
}
548556
case LLVMMul: {
549557
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
550558
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
559+
LLVMBool NUW = LLVMGetNUW(Src);
560+
LLVMBool NSW = LLVMGetNSW(Src);
551561
Dst = LLVMBuildMul(Builder, LHS, RHS, Name);
562+
LLVMSetNUW(Dst, NUW);
563+
LLVMSetNSW(Dst, NSW);
552564
break;
553565
}
554566
case LLVMUDiv: {
555567
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
556568
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
569+
LLVMBool IsExact = LLVMGetExact(Src);
557570
Dst = LLVMBuildUDiv(Builder, LHS, RHS, Name);
571+
LLVMSetExact(Dst, IsExact);
558572
break;
559573
}
560574
case LLVMSDiv: {
561575
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
562576
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
577+
LLVMBool IsExact = LLVMGetExact(Src);
563578
Dst = LLVMBuildSDiv(Builder, LHS, RHS, Name);
579+
LLVMSetExact(Dst, IsExact);
564580
break;
565581
}
566582
case LLVMURem: {
@@ -578,19 +594,27 @@ struct FunCloner {
578594
case LLVMShl: {
579595
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
580596
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
597+
LLVMBool NUW = LLVMGetNUW(Src);
598+
LLVMBool NSW = LLVMGetNSW(Src);
581599
Dst = LLVMBuildShl(Builder, LHS, RHS, Name);
600+
LLVMSetNUW(Dst, NUW);
601+
LLVMSetNSW(Dst, NSW);
582602
break;
583603
}
584604
case LLVMLShr: {
585605
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
586606
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
607+
LLVMBool IsExact = LLVMGetExact(Src);
587608
Dst = LLVMBuildLShr(Builder, LHS, RHS, Name);
609+
LLVMSetExact(Dst, IsExact);
588610
break;
589611
}
590612
case LLVMAShr: {
591613
LLVMValueRef LHS = CloneValue(LLVMGetOperand(Src, 0));
592614
LLVMValueRef RHS = CloneValue(LLVMGetOperand(Src, 1));
615+
LLVMBool IsExact = LLVMGetExact(Src);
593616
Dst = LLVMBuildAShr(Builder, LHS, RHS, Name);
617+
LLVMSetExact(Dst, IsExact);
594618
break;
595619
}
596620
case LLVMAnd: {

0 commit comments

Comments
 (0)