diff --git a/llvm/lib/Analysis/InstructionSimplify.cpp b/llvm/lib/Analysis/InstructionSimplify.cpp --- a/llvm/lib/Analysis/InstructionSimplify.cpp +++ b/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 diff --git a/llvm/test/Transforms/InstCombine/pr62607.ll b/llvm/test/Transforms/InstCombine/pr62607.ll new file mode 100644 --- /dev/null +++ b/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 +}