From 80a316fff0eb293b62d3d78dcd981f3e529aea2d Mon Sep 17 00:00:00 2001 From: Jorge Botto Date: Sat, 3 Aug 2024 16:20:59 +0100 Subject: [PATCH 1/4] Precommit test --- .../InstCombine/intrinsic-distributive.ll | 571 ++++++++++++++++++ 1 file changed, 571 insertions(+) create mode 100644 llvm/test/Transforms/InstCombine/intrinsic-distributive.ll diff --git a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll new file mode 100644 index 0000000000000..acd05e1605478 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll @@ -0,0 +1,571 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 +; RUN: opt -S -passes=instcombine < %s 2>&1 | FileCheck %s + + +define i8 @umax_of_add_nuw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw i8 %c, %a + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @umax_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[A]], [[C]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw i8 %a, %b + %add2 = add nuw i8 %a, %c + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @umax_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw nsw i8 %b, %a + %add2 = add nuw i8 %c, %a + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @umax_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[A]], [[C]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nuw i8 %a, %c + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @umax_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw nsw i8 %c, %a + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @umax_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw i8 %a, %b + %add2 = add nuw nsw i8 %a, %c + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @umax_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw nsw i8 %b, %a + %add2 = add nuw nsw i8 %c, %a + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @umax_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nuw nsw i8 %a, %c + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +; negative test +define i8 @umax_of_add_nsw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add_nsw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw i8 %c, %a + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +; negative test +define i8 @umax_of_add(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umax_of_add( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add i8 %b, %a + %add2 = add i8 %c, %a + %max = call i8 @llvm.umax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @umin_of_add_nuw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw i8 %c, %a + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @umin_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[A]], [[C]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw i8 %a, %b + %add2 = add nuw i8 %a, %c + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @umin_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw nsw i8 %b, %a + %add2 = add nuw i8 %c, %a + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @umin_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[A]], [[C]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nuw i8 %a, %c + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @umin_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw nsw i8 %c, %a + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @umin_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw i8 %a, %b + %add2 = add nuw nsw i8 %a, %c + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @umin_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw nsw i8 %b, %a + %add2 = add nuw nsw i8 %c, %a + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @umin_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw nsw i8 %a, %b + %add2 = add nuw nsw i8 %a, %c + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +; negative test +define i8 @umin_of_add_nsw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add_nsw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw i8 %c, %a + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +; negative test +define i8 @umin_of_add(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @umin_of_add( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add i8 %b, %a + %add2 = add i8 %c, %a + %min = call i8 @llvm.umin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +; negative test +define i8 @smax_of_add_nuw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nuw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw i8 %c, %a + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @smax_of_add_nsw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw i8 %c, %a + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @smax_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw i8 %a, %b + %add2 = add nsw i8 %a, %c + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @smax_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw nuw i8 %b, %a + %add2 = add nsw i8 %c, %a + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @smax_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw nuw i8 %a, %b + %add2 = add nsw i8 %a, %c + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @smax_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw nuw i8 %c, %a + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @smax_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw i8 %a, %b + %add2 = add nsw nuw i8 %a, %c + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @smax_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw nuw i8 %b, %a + %add2 = add nsw nuw i8 %c, %a + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +define i8 @smax_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add nsw nuw i8 %a, %b + %add2 = add nsw nuw i8 %a, %c + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +; negative test +define i8 @smax_of_add(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smax_of_add( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add i8 [[C]], [[A]] +; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MAX]] +; + %add1 = add i8 %b, %a + %add2 = add i8 %c, %a + %max = call i8 @llvm.smax.i8(i8 %add1, i8 %add2) + ret i8 %max +} + +; negative test +define i8 @smin_of_add_nuw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nuw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nuw i8 %b, %a + %add2 = add nuw i8 %c, %a + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @smin_of_add_nsw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw i8 %c, %a + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @smin_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw i8 %a, %b + %add2 = add nsw i8 %a, %c + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @smin_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw nuw i8 %b, %a + %add2 = add nsw i8 %c, %a + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @smin_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw nuw i8 %a, %b + %add2 = add nsw i8 %a, %c + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @smin_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw i8 %b, %a + %add2 = add nsw nuw i8 %c, %a + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @smin_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw i8 %a, %b + %add2 = add nsw nuw i8 %a, %c + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @smin_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw nuw i8 %b, %a + %add2 = add nsw nuw i8 %c, %a + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +define i8 @smin_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_comm( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add nsw nuw i8 %a, %b + %add2 = add nsw nuw i8 %a, %c + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} + +; negative test +define i8 @smin_of_add(i8 %a, i8 %b, i8 %c) { +; CHECK-LABEL: define i8 @smin_of_add( +; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { +; CHECK-NEXT: [[ADD1:%.*]] = add i8 [[B]], [[A]] +; CHECK-NEXT: [[ADD2:%.*]] = add i8 [[C]], [[A]] +; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: ret i8 [[MIN]] +; + %add1 = add i8 %b, %a + %add2 = add i8 %c, %a + %min = call i8 @llvm.smin.i8(i8 %add1, i8 %add2) + ret i8 %min +} From ced8dbaa94e03f97b17744c5abec31605300f0c3 Mon Sep 17 00:00:00 2001 From: Jorge Botto Date: Sat, 3 Aug 2024 17:10:39 +0100 Subject: [PATCH 2/4] Adding missed optimisation --- llvm/include/llvm/IR/Operator.h | 3 + .../InstCombine/InstCombineCalls.cpp | 73 ++++++++ .../InstCombine/intrinsic-distributive.ll | 160 +++++++----------- 3 files changed, 140 insertions(+), 96 deletions(-) diff --git a/llvm/include/llvm/IR/Operator.h b/llvm/include/llvm/IR/Operator.h index f63f54ef94107..d0a0242ec657d 100644 --- a/llvm/include/llvm/IR/Operator.h +++ b/llvm/include/llvm/IR/Operator.h @@ -123,6 +123,9 @@ class OverflowingBinaryOperator : public Operator { return NoWrapKind; } + /// Return true if the instruction is commutative + bool isCommutative() const { return Instruction::isCommutative(getOpcode()); } + static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Add || I->getOpcode() == Instruction::Sub || diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 2c2e1bc4686a4..6596e74fd6168 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1503,6 +1503,76 @@ foldMinimumOverTrailingOrLeadingZeroCount(Value *I0, Value *I1, ConstantInt::getTrue(ZeroUndef->getType())); } +/// Return whether "X LOp (Y ROp Z)" is always equal to +/// "(X LOp Y) ROp (X LOp Z)". +static bool leftDistributesOverRight(Instruction::BinaryOps LOp, bool hasNUW, + bool hasNSW, Intrinsic::ID ROp) { + switch (ROp) { + case Intrinsic::umax: + case Intrinsic::umin: + return hasNUW && LOp == Instruction::Add; + case Intrinsic::smax: + case Intrinsic::smin: + return hasNSW && LOp == Instruction::Add; + default: + return false; + } +} + +// Attempts to factorise a common term +// in an instruction that has the form "(A op' B) op (C op' D) +// where op is an intrinsic and op' is a binop +static Value * +foldIntrinsicUsingDistributiveLaws(IntrinsicInst *II, + InstCombiner::BuilderTy &Builder) { + Value *LHS = II->getOperand(0), *RHS = II->getOperand(1); + Intrinsic::ID TopLevelOpcode = II->getIntrinsicID(); + + OverflowingBinaryOperator *Op0 = dyn_cast(LHS); + OverflowingBinaryOperator *Op1 = dyn_cast(RHS); + + if (!Op0 || !Op1) + return nullptr; + + if (Op0->getOpcode() != Op1->getOpcode()) + return nullptr; + + if (!Op0->hasOneUse() || !Op1->hasOneUse()) + return nullptr; + + Instruction::BinaryOps InnerOpcode = + static_cast(Op0->getOpcode()); + bool HasNUW = Op0->hasNoUnsignedWrap() && Op1->hasNoUnsignedWrap(); + bool HasNSW = Op0->hasNoSignedWrap() && Op1->hasNoSignedWrap(); + + if (!leftDistributesOverRight(InnerOpcode, HasNUW, HasNSW, TopLevelOpcode)) + return nullptr; + + assert(II->isCommutative() && Op0->isCommutative() && + "Only inner and outer commutative op codes are supported."); + + Value *A = Op0->getOperand(0); + Value *B = Op0->getOperand(1); + Value *C = Op1->getOperand(0); + Value *D = Op1->getOperand(1); + + // Attempts to swap variables such that A always equals C + if (A != C && A != D) + std::swap(A, B); + if (A == C || A == D) { + if (A != C) + std::swap(C, D); + Value *NewIntrinsic = Builder.CreateBinaryIntrinsic(TopLevelOpcode, B, D); + BinaryOperator *NewBinop = + cast(Builder.CreateBinOp(InnerOpcode, NewIntrinsic, A)); + NewBinop->setHasNoSignedWrap(HasNSW); + NewBinop->setHasNoUnsignedWrap(HasNUW); + return NewBinop; + } + + return nullptr; +} + /// CallInst simplification. This mostly only handles folding of intrinsic /// instructions. For normal calls, it allows visitCallBase to do the heavy /// lifting. @@ -1927,6 +1997,9 @@ Instruction *InstCombinerImpl::visitCallInst(CallInst &CI) { } } + if (Value *V = foldIntrinsicUsingDistributiveLaws(II, Builder)) + return replaceInstUsesWith(*II, V); + break; } case Intrinsic::bitreverse: { diff --git a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll index acd05e1605478..2284e3f6c174b 100644 --- a/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll +++ b/llvm/test/Transforms/InstCombine/intrinsic-distributive.ll @@ -5,9 +5,8 @@ define i8 @umax_of_add_nuw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %b, %a @@ -19,9 +18,8 @@ define i8 @umax_of_add_nuw(i8 %a, i8 %b, i8 %c) { define i8 @umax_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[A]], [[C]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %a, %b @@ -33,9 +31,8 @@ define i8 @umax_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { define i8 @umax_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %b, %a @@ -47,9 +44,8 @@ define i8 @umax_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { define i8 @umax_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_lhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[A]], [[C]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -61,9 +57,8 @@ define i8 @umax_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { define i8 @umax_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %b, %a @@ -75,9 +70,8 @@ define i8 @umax_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { define i8 @umax_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_rhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw i8 %a, %b @@ -89,9 +83,8 @@ define i8 @umax_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { define i8 @umax_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %b, %a @@ -103,9 +96,8 @@ define i8 @umax_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { define i8 @umax_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umax_of_add_nuw_nsw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.umax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nuw nsw i8 %a, %b @@ -147,9 +139,8 @@ define i8 @umax_of_add(i8 %a, i8 %b, i8 %c) { define i8 @umin_of_add_nuw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %b, %a @@ -161,9 +152,8 @@ define i8 @umin_of_add_nuw(i8 %a, i8 %b, i8 %c) { define i8 @umin_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[A]], [[C]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %a, %b @@ -175,9 +165,8 @@ define i8 @umin_of_add_nuw_comm(i8 %a, i8 %b, i8 %c) { define i8 @umin_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[C]], [[A]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %b, %a @@ -189,9 +178,8 @@ define i8 @umin_of_add_nuw_nsw_lhs(i8 %a, i8 %b, i8 %c) { define i8 @umin_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_lhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw i8 [[A]], [[C]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -203,9 +191,8 @@ define i8 @umin_of_add_nuw_nsw_lhs_comm(i8 %a, i8 %b, i8 %c) { define i8 @umin_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %b, %a @@ -217,9 +204,8 @@ define i8 @umin_of_add_nuw_nsw_rhs(i8 %a, i8 %b, i8 %c) { define i8 @umin_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_rhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw i8 %a, %b @@ -231,9 +217,8 @@ define i8 @umin_of_add_nuw_nsw_rhs_comm(i8 %a, i8 %b, i8 %c) { define i8 @umin_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %b, %a @@ -245,9 +230,8 @@ define i8 @umin_of_add_nuw_nsw(i8 %a, i8 %b, i8 %c) { define i8 @umin_of_add_nuw_nsw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @umin_of_add_nuw_nsw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.umin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.umin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nuw nsw i8 %a, %b @@ -304,9 +288,8 @@ define i8 @smax_of_add_nuw(i8 %a, i8 %b, i8 %c) { define i8 @smax_of_add_nsw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %b, %a @@ -318,9 +301,8 @@ define i8 @smax_of_add_nsw(i8 %a, i8 %b, i8 %c) { define i8 @smax_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %a, %b @@ -332,9 +314,8 @@ define i8 @smax_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { define i8 @smax_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %b, %a @@ -346,9 +327,8 @@ define i8 @smax_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { define i8 @smax_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_lhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -360,9 +340,8 @@ define i8 @smax_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { define i8 @smax_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %b, %a @@ -374,9 +353,8 @@ define i8 @smax_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { define i8 @smax_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_rhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw i8 %a, %b @@ -388,9 +366,8 @@ define i8 @smax_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { define i8 @smax_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %b, %a @@ -402,9 +379,8 @@ define i8 @smax_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { define i8 @smax_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smax_of_add_nsw_nuw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MAX:%.*]] = call i8 @llvm.smax.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smax.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MAX:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MAX]] ; %add1 = add nsw nuw i8 %a, %b @@ -446,9 +422,8 @@ define i8 @smin_of_add_nuw(i8 %a, i8 %b, i8 %c) { define i8 @smin_of_add_nsw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %b, %a @@ -460,9 +435,8 @@ define i8 @smin_of_add_nsw(i8 %a, i8 %b, i8 %c) { define i8 @smin_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %a, %b @@ -474,9 +448,8 @@ define i8 @smin_of_add_nsw_comm(i8 %a, i8 %b, i8 %c) { define i8 @smin_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %b, %a @@ -488,9 +461,8 @@ define i8 @smin_of_add_nsw_nuw_lhs(i8 %a, i8 %b, i8 %c) { define i8 @smin_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_lhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b @@ -502,9 +474,8 @@ define i8 @smin_of_add_nsw_nuw_lhs_comm(i8 %a, i8 %b, i8 %c) { define i8 @smin_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %b, %a @@ -516,9 +487,8 @@ define i8 @smin_of_add_nsw_nuw_rhs(i8 %a, i8 %b, i8 %c) { define i8 @smin_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_rhs_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw i8 %a, %b @@ -530,9 +500,8 @@ define i8 @smin_of_add_nsw_nuw_rhs_comm(i8 %a, i8 %b, i8 %c) { define i8 @smin_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[B]], [[A]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[C]], [[A]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %b, %a @@ -544,9 +513,8 @@ define i8 @smin_of_add_nsw_nuw(i8 %a, i8 %b, i8 %c) { define i8 @smin_of_add_nsw_nuw_comm(i8 %a, i8 %b, i8 %c) { ; CHECK-LABEL: define i8 @smin_of_add_nsw_nuw_comm( ; CHECK-SAME: i8 [[A:%.*]], i8 [[B:%.*]], i8 [[C:%.*]]) { -; CHECK-NEXT: [[ADD1:%.*]] = add nuw nsw i8 [[A]], [[B]] -; CHECK-NEXT: [[ADD2:%.*]] = add nuw nsw i8 [[A]], [[C]] -; CHECK-NEXT: [[MIN:%.*]] = call i8 @llvm.smin.i8(i8 [[ADD1]], i8 [[ADD2]]) +; CHECK-NEXT: [[TMP1:%.*]] = call i8 @llvm.smin.i8(i8 [[B]], i8 [[C]]) +; CHECK-NEXT: [[MIN:%.*]] = add nuw nsw i8 [[TMP1]], [[A]] ; CHECK-NEXT: ret i8 [[MIN]] ; %add1 = add nsw nuw i8 %a, %b From 6631dda15addc8b2557a1a9591ca84139161d40e Mon Sep 17 00:00:00 2001 From: Jorge Botto Date: Wed, 21 Aug 2024 14:21:16 +0100 Subject: [PATCH 3/4] Update llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp Co-authored-by: Yingwei Zheng --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 6596e74fd6168..4ddc1d3385157 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1505,8 +1505,8 @@ foldMinimumOverTrailingOrLeadingZeroCount(Value *I0, Value *I1, /// Return whether "X LOp (Y ROp Z)" is always equal to /// "(X LOp Y) ROp (X LOp Z)". -static bool leftDistributesOverRight(Instruction::BinaryOps LOp, bool hasNUW, - bool hasNSW, Intrinsic::ID ROp) { +static bool leftDistributesOverRight(Instruction::BinaryOps LOp, bool HasNUW, + bool HasNSW, Intrinsic::ID ROp) { switch (ROp) { case Intrinsic::umax: case Intrinsic::umin: From 98235c2efb1a9f83dd6d658d8e6a7597eec70a98 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sat, 2 Nov 2024 16:21:21 +0100 Subject: [PATCH 4/4] Update llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp --- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 2981ae2b6c78a..6cff3c7af91e3 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1510,10 +1510,10 @@ static bool leftDistributesOverRight(Instruction::BinaryOps LOp, bool HasNUW, switch (ROp) { case Intrinsic::umax: case Intrinsic::umin: - return hasNUW && LOp == Instruction::Add; + return HasNUW && LOp == Instruction::Add; case Intrinsic::smax: case Intrinsic::smin: - return hasNSW && LOp == Instruction::Add; + return HasNSW && LOp == Instruction::Add; default: return false; }