diff options
author | Philip Reames <listmail@philipreames.com> | 2019-07-09 18:56:41 +0000 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2019-07-09 18:56:41 +0000 |
commit | 3b38b92541d78f4afba2d0bea737e53d2fae4511 (patch) | |
tree | 61b2b689e4576d076d9ad1699dd6ce7f9a17a764 | |
parent | 6a4c2e4f0a933f24b9f089e3804072f7733e38eb (diff) | |
download | bcm5719-llvm-3b38b92541d78f4afba2d0bea737e53d2fae4511.tar.gz bcm5719-llvm-3b38b92541d78f4afba2d0bea737e53d2fae4511.zip |
[PoisonChecking] Add validation rules for "exact" on sdiv/udiv
As directly stated in the LangRef, no ambiguity here...
llvm-svn: 365538
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp | 18 | ||||
-rw-r--r-- | llvm/test/Instrumentation/PoisonChecking/basic-flag-validation.ll | 43 |
2 files changed, 61 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp b/llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp index 8406eb5d396..8e4c046c9f8 100644 --- a/llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp +++ b/llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp @@ -151,6 +151,24 @@ static void generatePoisonChecksForBinOp(Instruction &I, } break; } + case Instruction::UDiv: { + if (I.isExact()) { + auto *Check = + B.CreateICmp(ICmpInst::ICMP_NE, B.CreateURem(LHS, RHS), + ConstantInt::get(LHS->getType(), 0)); + Checks.push_back(Check); + } + break; + } + case Instruction::SDiv: { + if (I.isExact()) { + auto *Check = + B.CreateICmp(ICmpInst::ICMP_NE, B.CreateSRem(LHS, RHS), + ConstantInt::get(LHS->getType(), 0)); + Checks.push_back(Check); + } + break; + } }; } diff --git a/llvm/test/Instrumentation/PoisonChecking/basic-flag-validation.ll b/llvm/test/Instrumentation/PoisonChecking/basic-flag-validation.ll index e3a0c0660fd..9fb491653fa 100644 --- a/llvm/test/Instrumentation/PoisonChecking/basic-flag-validation.ll +++ b/llvm/test/Instrumentation/PoisonChecking/basic-flag-validation.ll @@ -156,3 +156,46 @@ define i32 @mul_nsw_nuw(i32 %a, i32 %b) { ret i32 %res } +define i32 @sdiv_noflags(i32 %a, i32 %b) { +; CHECK-LABEL: @sdiv_noflags( +; CHECK-NEXT: [[RES:%.*]] = sdiv i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: ret i32 [[RES]] +; + %res = sdiv i32 %a, %b + ret i32 %res +} + +define i32 @sdiv_exact(i32 %a, i32 %b) { +; CHECK-LABEL: @sdiv_exact( +; CHECK-NEXT: [[TMP1:%.*]] = srem i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 +; CHECK-NEXT: [[RES:%.*]] = sdiv exact i32 [[A]], [[B]] +; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true +; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) +; CHECK-NEXT: ret i32 [[RES]] +; + %res = sdiv exact i32 %a, %b + ret i32 %res +} + +define i32 @udiv_noflags(i32 %a, i32 %b) { +; CHECK-LABEL: @udiv_noflags( +; CHECK-NEXT: [[RES:%.*]] = udiv i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: ret i32 [[RES]] +; + %res = udiv i32 %a, %b + ret i32 %res +} + +define i32 @udiv_exact(i32 %a, i32 %b) { +; CHECK-LABEL: @udiv_exact( +; CHECK-NEXT: [[TMP1:%.*]] = urem i32 [[A:%.*]], [[B:%.*]] +; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0 +; CHECK-NEXT: [[RES:%.*]] = udiv exact i32 [[A]], [[B]] +; CHECK-NEXT: [[TMP3:%.*]] = xor i1 [[TMP2]], true +; CHECK-NEXT: call void @__poison_checker_assert(i1 [[TMP3]]) +; CHECK-NEXT: ret i32 [[RES]] +; + %res = udiv exact i32 %a, %b + ret i32 %res +} |