[PATCH] D150141: [InstCombine] Add simplifications for div/rem with `i1` operands; PR62607

Noah Goldstein via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 8 13:30:15 PDT 2023


goldstein.w.n created this revision.
goldstein.w.n added reviewers: spatel, nikic.
Herald added subscribers: StephenFan, hiraditya.
Herald added a project: All.
goldstein.w.n requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

This is generally handled already in early CSE and/or generically with
valuetracking.

`InstCombine` assumes that div/rem with `i1` operands will have
already been handled which is not always the case if a non-standard
pipeline is being used:
https://github.com/llvm/llvm-project/issues/62607

This just adds `i1` handling to `InstructionSimplify` so that
`InstCombine's` assumptions are fulfilled by itself.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150141

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstCombine/pr62607.ll


Index: llvm/test/Transforms/InstCombine/pr62607.ll
===================================================================
--- /dev/null
+++ llvm/test/Transforms/InstCombine/pr62607.ll
@@ -0,0 +1,64 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -S -passes=instcombine < %s | FileCheck %s
+
+source_filename = "gen_06283"
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i1 @llvm.umax.i1(i1, i1) #0
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i8 @llvm.smin.i8(i8, i8) #0
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i8 @llvm.umin.i8(i8, i8) #0
+
+; Function Attrs: nocallback nofree nosync nounwind speculatable willreturn memory(none)
+declare i16 @llvm.umax.i16(i16, i16) #0
+
+; Function Attrs: nocallback nofree nosync nounwind willreturn memory(inaccessiblemem: readwrite)
+declare void @llvm.assume(i1 noundef) #1
+
+define i1 @function_0(i8 %val_i8_9, i8 %val_i8_10, i16 %val_i16_11, i1 %val_i1_12) {
+entry_1:
+  %val_i16_22 = freeze i16 %val_i16_11
+  %val_i1_38 = trunc i8 109 to i1
+  %val_i8_39 = sext i1 %val_i1_12 to i8
+  %val_i64_41 = zext i32 1870136903 to i64
+  br label %bb_3
+bb_2:  ; preds = %bb_6, %bb_2
+  %val_i64_44 = sext i16 %val_i16_11 to i64
+  %val_i8_45 = trunc i32 378764218 to i8
+  %val_i16_46 = trunc i32 -1932311229 to i16
+  %val_i1_47 = icmp sgt i32 -1106208892, -764213229
+  %val_i64_49 = xor i64 %val_i64_41, %val_i64_44
+  %val_i1_51 = trunc i16 %val_i16_46 to i1
+  br i1 %val_i1_12, label %bb_2, label %bb_3
+bb_3:  ; preds = %bb_2, %entry_1
+  br label %prhdr_loop_4
+prhdr_loop_4:  ; preds = %bb_3
+  br label %loop_5
+loop_5:  ; preds = %be_7, %prhdr_loop_4
+  %loop_cnt_i1_26.0 = phi i1 [ false, %prhdr_loop_4 ], [ %val_i1_55, %be_7 ]
+  %val_i1_55 = add i1 %loop_cnt_i1_26.0, true
+  call void @llvm.assume(i1 %val_i1_12)
+  %val_i16_56 = call i16 @llvm.umax.i16(i16 %val_i16_22, i16 %val_i16_11)
+  br i1 %val_i1_12, label %be_7, label %loop_exit_8
+bb_6:  ; preds = %loop_exit_8, %bb_6
+  %val_i16_57 = zext i8 undef to i16
+  br i1 %loop_cnt_i1_26.0, label %bb_6, label %bb_2
+be_7:  ; preds = %loop_5
+  %val_i1_58 = call i1 @llvm.umax.i1(i1 %val_i1_38, i1 %val_i1_55)
+  %val_i8_60 = trunc i64 %val_i64_41 to i8
+  %val_i8_61 = call i8 @llvm.smin.i8(i8 %val_i8_60, i8 undef)
+  %val_i1_62 = icmp sle i32 -1472218002, 1177808965
+  %val_i8_64 = call i8 @llvm.umin.i8(i8 %val_i8_61, i8 %val_i8_60)
+  %val_i1_65 = icmp ule i8 %val_i8_61, undef
+  %val_i16_66 = call i16 @llvm.umax.i16(i16 %val_i16_11, i16 %val_i16_22)
+  call void @llvm.assume(i1 %val_i1_55)
+  %val_i1_67 = udiv i1 %val_i1_38, %loop_cnt_i1_26.0
+  br i1 %val_i1_67, label %loop_5, label %loop_exit_8
+loop_exit_8:  ; preds = %be_7, %loop_5
+  br label %bb_6
+}
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -1139,6 +1139,15 @@
   if (Known.countMinLeadingZeros() == Known.getBitWidth() - 1)
     return IsDiv ? Op0 : Constant::getNullValue(Ty);
 
+  // i1_X / i1_Y -> i1_X
+  // i1_X % i1_Y -> false
+  if (Ty->isIntOrIntVectorTy(1)) {
+      if(Opcode == Instruction::UDiv || Opcode == Instruction::SDiv )
+          return Op0;
+      else
+          return Constant::getNullValue(Ty);
+  }
+
   // If X * Y does not overflow, then:
   //   X * Y / Y -> X
   //   X * Y % Y -> 0


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150141.520471.patch
Type: text/x-patch
Size: 3678 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230508/8c4fa96b/attachment.bin>


More information about the llvm-commits mailing list