| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 |
| ; RUN: opt -passes=instcombine -S < %s | FileCheck %s |
| |
| declare void @dummy() |
| |
| declare i32 @llvm.smax.i32(i32 %a, i32 %b) |
| declare i32 @llvm.smin.i32(i32 %a, i32 %b) |
| declare i32 @llvm.umax.i32(i32 %a, i32 %b) |
| declare i32 @llvm.umin.i32(i32 %a, i32 %b) |
| declare float @llvm.maxnum.f32(float %a, float %b) |
| declare float @llvm.minnum.f32(float %a, float %b) |
| declare float @llvm.maximum.f32(float %a, float %b) |
| declare float @llvm.minimum.f32(float %a, float %b) |
| declare float @llvm.pow.f32(float %a, float %b) |
| |
| define i8 @fold_phi_mul(i1 %c, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_mul( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%b, %entry], [%a, %then] |
| %ret = mul i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| define i8 @fold_phi_mul_three(i1 %c, i1 %d, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_mul_three( |
| ; CHECK-SAME: i1 [[C:%.*]], i1 [[D:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN1:%.*]], label [[END:%.*]] |
| ; CHECK: then1: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br i1 [[D]], label [[THEN2:%.*]], label [[END]] |
| ; CHECK: then2: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then1, label %end |
| then1: |
| call void @dummy() |
| br i1 %d, label %then2, label %end |
| then2: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then1], [%a, %then2] |
| %phi2 = phi i8 [%b, %entry], [%a, %then1], [%b, %then2] |
| %ret = mul i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| define i8 @fold_phi_mul_three_notopt(i1 %c, i1 %d, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_mul_three_notopt( |
| ; CHECK-SAME: i1 [[C:%.*]], i1 [[D:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN1:%.*]], label [[END:%.*]] |
| ; CHECK: then1: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br i1 [[D]], label [[THEN2:%.*]], label [[END]] |
| ; CHECK: then2: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN1]] ], [ [[A]], [[THEN2]] ] |
| ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN1]] ], [ [[A]], [[THEN2]] ] |
| ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[PHI1]], [[PHI2]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then1, label %end |
| then1: |
| call void @dummy() |
| br i1 %d, label %then2, label %end |
| then2: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then1], [%a, %then2] |
| %phi2 = phi i8 [%b, %entry], [%a, %then1], [%a, %then2] |
| %ret = mul i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| define i8 @fold_phi_mul_nsw_nuw(i1 %c, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_mul_nsw_nuw( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = mul nuw nsw i8 [[A]], [[B]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%b, %entry], [%a, %then] |
| %ret = mul nsw nuw i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| define <2 x i8> @fold_phi_mul_fix_vec(i1 %c, <2 x i8> %a, <2 x i8> %b) { |
| ; CHECK-LABEL: define <2 x i8> @fold_phi_mul_fix_vec( |
| ; CHECK-SAME: i1 [[C:%.*]], <2 x i8> [[A:%.*]], <2 x i8> [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = mul <2 x i8> [[A]], [[B]] |
| ; CHECK-NEXT: ret <2 x i8> [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi <2 x i8> [%a, %entry], [%b, %then] |
| %phi2 = phi <2 x i8> [%b, %entry], [%a, %then] |
| %ret = mul <2 x i8> %phi1, %phi2 |
| ret <2 x i8> %ret |
| } |
| |
| define <vscale x 2 x i8> @fold_phi_mul_scale_vec(i1 %c, <vscale x 2 x i8> %a, <vscale x 2 x i8> %b) { |
| ; CHECK-LABEL: define <vscale x 2 x i8> @fold_phi_mul_scale_vec( |
| ; CHECK-SAME: i1 [[C:%.*]], <vscale x 2 x i8> [[A:%.*]], <vscale x 2 x i8> [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = mul <vscale x 2 x i8> [[A]], [[B]] |
| ; CHECK-NEXT: ret <vscale x 2 x i8> [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi <vscale x 2 x i8> [%a, %entry], [%b, %then] |
| %phi2 = phi <vscale x 2 x i8> [%b, %entry], [%a, %then] |
| %ret = mul <vscale x 2 x i8> %phi1, %phi2 |
| ret <vscale x 2 x i8> %ret |
| } |
| |
| define i8 @fold_phi_mul_commute(i1 %c, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_mul_commute( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[A]], [[B]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%a, %then], [%b, %entry] |
| %ret = mul i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| |
| define i8 @fold_phi_mul_notopt(i1 %c, i8 %a, i8 %b, i8 %d) { |
| ; CHECK-LABEL: define i8 @fold_phi_mul_notopt( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]], i8 [[D:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] |
| ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[D]], [[THEN]] ] |
| ; CHECK-NEXT: [[RET:%.*]] = mul i8 [[PHI1]], [[PHI2]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%b, %entry], [%d, %then] |
| %ret = mul i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| |
| define i8 @fold_phi_sub(i1 %c, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_sub( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[PHI1:%.*]] = phi i8 [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] |
| ; CHECK-NEXT: [[PHI2:%.*]] = phi i8 [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN]] ] |
| ; CHECK-NEXT: [[RET:%.*]] = sub i8 [[PHI1]], [[PHI2]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%b, %entry], [%a, %then] |
| %ret = sub i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| |
| define i8 @fold_phi_add(i1 %c, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_add( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = add i8 [[A]], [[B]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%b, %entry], [%a, %then] |
| %ret = add i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| define i8 @fold_phi_and(i1 %c, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_and( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = and i8 [[A]], [[B]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%b, %entry], [%a, %then] |
| %ret = and i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| define i8 @fold_phi_or(i1 %c, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_or( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = or i8 [[A]], [[B]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%b, %entry], [%a, %then] |
| %ret = or i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| |
| define i8 @fold_phi_xor(i1 %c, i8 %a, i8 %b) { |
| ; CHECK-LABEL: define i8 @fold_phi_xor( |
| ; CHECK-SAME: i1 [[C:%.*]], i8 [[A:%.*]], i8 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = xor i8 [[A]], [[B]] |
| ; CHECK-NEXT: ret i8 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i8 [%a, %entry], [%b, %then] |
| %phi2 = phi i8 [%b, %entry], [%a, %then] |
| %ret = xor i8 %phi1, %phi2 |
| ret i8 %ret |
| } |
| |
| |
| define float @fold_phi_fadd(i1 %c, float %a, float %b) { |
| ; CHECK-LABEL: define float @fold_phi_fadd( |
| ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = fadd float [[A]], [[B]] |
| ; CHECK-NEXT: ret float [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi float [%a, %entry], [%b, %then] |
| %phi2 = phi float [%b, %entry], [%a, %then] |
| %ret = fadd float %phi1, %phi2 |
| ret float %ret |
| } |
| |
| define float @fold_phi_fadd_nnan(i1 %c, float %a, float %b) { |
| ; CHECK-LABEL: define float @fold_phi_fadd_nnan( |
| ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = fadd nnan float [[A]], [[B]] |
| ; CHECK-NEXT: ret float [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi float [%a, %entry], [%b, %then] |
| %phi2 = phi float [%b, %entry], [%a, %then] |
| %ret = fadd nnan float %phi1, %phi2 |
| ret float %ret |
| } |
| |
| |
| define float @fold_phi_fmul(i1 %c, float %a, float %b) { |
| ; CHECK-LABEL: define float @fold_phi_fmul( |
| ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = fmul float [[A]], [[B]] |
| ; CHECK-NEXT: ret float [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi float [%a, %entry], [%b, %then] |
| %phi2 = phi float [%b, %entry], [%a, %then] |
| %ret = fmul float %phi1, %phi2 |
| ret float %ret |
| } |
| |
| |
| define i32 @fold_phi_smax(i1 %c, i32 %a, i32 %b) { |
| ; CHECK-LABEL: define i32 @fold_phi_smax( |
| ; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.smax.i32(i32 [[A]], i32 [[B]]) |
| ; CHECK-NEXT: ret i32 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i32 [%a, %entry], [%b, %then] |
| %phi2 = phi i32 [%b, %entry], [%a, %then] |
| %ret = call i32 @llvm.smax.i32(i32 %phi1, i32 %phi2) |
| ret i32 %ret |
| } |
| |
| |
| define i32 @fold_phi_smin(i1 %c, i32 %a, i32 %b) { |
| ; CHECK-LABEL: define i32 @fold_phi_smin( |
| ; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.smin.i32(i32 [[A]], i32 [[B]]) |
| ; CHECK-NEXT: ret i32 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i32 [%a, %entry], [%b, %then] |
| %phi2 = phi i32 [%b, %entry], [%a, %then] |
| %ret = call i32 @llvm.smin.i32(i32 %phi1, i32 %phi2) |
| ret i32 %ret |
| } |
| |
| |
| define i32 @fold_phi_umax(i1 %c, i32 %a, i32 %b) { |
| ; CHECK-LABEL: define i32 @fold_phi_umax( |
| ; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umax.i32(i32 [[A]], i32 [[B]]) |
| ; CHECK-NEXT: ret i32 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i32 [%a, %entry], [%b, %then] |
| %phi2 = phi i32 [%b, %entry], [%a, %then] |
| %ret = call i32 @llvm.umax.i32(i32 %phi1, i32 %phi2) |
| ret i32 %ret |
| } |
| |
| define i32 @fold_phi_umin(i1 %c, i32 %a, i32 %b) { |
| ; CHECK-LABEL: define i32 @fold_phi_umin( |
| ; CHECK-SAME: i1 [[C:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = call i32 @llvm.umin.i32(i32 [[A]], i32 [[B]]) |
| ; CHECK-NEXT: ret i32 [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi i32 [%a, %entry], [%b, %then] |
| %phi2 = phi i32 [%b, %entry], [%a, %then] |
| %ret = call i32 @llvm.umin.i32(i32 %phi1, i32 %phi2) |
| ret i32 %ret |
| } |
| |
| |
| define float @fold_phi_maxnum(i1 %c, float %a, float %b) { |
| ; CHECK-LABEL: define float @fold_phi_maxnum( |
| ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.maxnum.f32(float [[A]], float [[B]]) |
| ; CHECK-NEXT: ret float [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi float [%a, %entry], [%b, %then] |
| %phi2 = phi float [%b, %entry], [%a, %then] |
| %ret = call float @llvm.maxnum.f32(float %phi1, float %phi2) |
| ret float %ret |
| } |
| |
| define float @fold_phi_pow(i1 %c, float %a, float %b) { |
| ; CHECK-LABEL: define float @fold_phi_pow( |
| ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[PHI1:%.*]] = phi float [ [[A]], [[ENTRY:%.*]] ], [ [[B]], [[THEN]] ] |
| ; CHECK-NEXT: [[PHI2:%.*]] = phi float [ [[B]], [[ENTRY]] ], [ [[A]], [[THEN]] ] |
| ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.pow.f32(float [[PHI1]], float [[PHI2]]) |
| ; CHECK-NEXT: ret float [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi float [%a, %entry], [%b, %then] |
| %phi2 = phi float [%b, %entry], [%a, %then] |
| %ret = call float @llvm.pow.f32(float %phi1, float %phi2) |
| ret float %ret |
| } |
| |
| define float @fold_phi_minnum(i1 %c, float %a, float %b) { |
| ; CHECK-LABEL: define float @fold_phi_minnum( |
| ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.minnum.f32(float [[A]], float [[B]]) |
| ; CHECK-NEXT: ret float [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi float [%a, %entry], [%b, %then] |
| %phi2 = phi float [%b, %entry], [%a, %then] |
| %ret = call float @llvm.minnum.f32(float %phi1, float %phi2) |
| ret float %ret |
| } |
| |
| define float @fold_phi_maximum(i1 %c, float %a, float %b) { |
| ; CHECK-LABEL: define float @fold_phi_maximum( |
| ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.maximum.f32(float [[A]], float [[B]]) |
| ; CHECK-NEXT: ret float [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi float [%a, %entry], [%b, %then] |
| %phi2 = phi float [%b, %entry], [%a, %then] |
| %ret = call float @llvm.maximum.f32(float %phi1, float %phi2) |
| ret float %ret |
| } |
| |
| define float @fold_phi_minimum(i1 %c, float %a, float %b) { |
| ; CHECK-LABEL: define float @fold_phi_minimum( |
| ; CHECK-SAME: i1 [[C:%.*]], float [[A:%.*]], float [[B:%.*]]) { |
| ; CHECK-NEXT: entry: |
| ; CHECK-NEXT: br i1 [[C]], label [[THEN:%.*]], label [[END:%.*]] |
| ; CHECK: then: |
| ; CHECK-NEXT: call void @dummy() |
| ; CHECK-NEXT: br label [[END]] |
| ; CHECK: end: |
| ; CHECK-NEXT: [[RET:%.*]] = call float @llvm.minimum.f32(float [[A]], float [[B]]) |
| ; CHECK-NEXT: ret float [[RET]] |
| ; |
| entry: |
| br i1 %c, label %then, label %end |
| then: |
| call void @dummy() |
| br label %end |
| end: |
| %phi1 = phi float [%a, %entry], [%b, %then] |
| %phi2 = phi float [%b, %entry], [%a, %then] |
| %ret = call float @llvm.minimum.f32(float %phi1, float %phi2) |
| ret float %ret |
| } |
| |