[PoisonChecking] Add validation rules for "exact" on sdiv/udiv
authorPhilip Reames <listmail@philipreames.com>
Tue, 9 Jul 2019 18:56:41 +0000 (18:56 +0000)
committerPhilip Reames <listmail@philipreames.com>
Tue, 9 Jul 2019 18:56:41 +0000 (18:56 +0000)
As directly stated in the LangRef, no ambiguity here...

llvm-svn: 365538

llvm/lib/Transforms/Instrumentation/PoisonChecking.cpp
llvm/test/Instrumentation/PoisonChecking/basic-flag-validation.ll

index 8406eb5..8e4c046 100644 (file)
@@ -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;
+  }
   };
 }
 
index e3a0c06..9fb4916 100644 (file)
@@ -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
+}