; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 ; RUN: opt < %s -passes=instsimplify -S | FileCheck %s define i32 @known_non_zero_by_or(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @known_non_zero_by_or( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[X]], 0 ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] ; CHECK: [[IF_THEN]]: ; CHECK-NEXT: [[VAL:%.*]] = or i32 [[X]], [[Y]] ; CHECK-NEXT: ret i32 [[VAL]] ; CHECK: [[IF_ELSE]]: ; CHECK-NEXT: ret i32 0 ; %cond = icmp ne i32 %x, 0 br i1 %cond, label %if.then, label %if.else if.then: %val = or i32 %x, %y %max = call i32 @llvm.umax.i32(i32 %val, i32 1) ret i32 %max if.else: ret i32 0 } define i32 @known_non_zero_by_mul(i32 %x) { ; CHECK-LABEL: define i32 @known_non_zero_by_mul( ; CHECK-SAME: i32 [[X:%.*]]) { ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[X]], 0 ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] ; CHECK: [[IF_THEN]]: ; CHECK-NEXT: [[NONZERO1:%.*]] = mul nuw i32 [[X]], 3 ; CHECK-NEXT: ret i32 [[NONZERO1]] ; CHECK: [[IF_ELSE]]: ; CHECK-NEXT: ret i32 0 ; %cond = icmp ne i32 %x, 0 br i1 %cond, label %if.then, label %if.else if.then: %nonzero = mul nuw i32 %x, 3 %max = call i32 @llvm.umax.i32(i32 %nonzero, i32 1) ret i32 %max if.else: ret i32 0 } define i32 @known_non_zero_commute(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @known_non_zero_commute( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[X]], 0 ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] ; CHECK: [[IF_THEN]]: ; CHECK-NEXT: [[VAL:%.*]] = or i32 [[X]], [[Y]] ; CHECK-NEXT: ret i32 [[VAL]] ; CHECK: [[IF_ELSE]]: ; CHECK-NEXT: ret i32 0 ; %cond = icmp ne i32 %x, 0 br i1 %cond, label %if.then, label %if.else if.then: %val = or i32 %x, %y %max = call i32 @llvm.umax.i32(i32 1, i32 %val) ret i32 %max if.else: ret i32 0 } ; Negative define i32 @umax_ge_2(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @umax_ge_2( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[X]], 0 ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] ; CHECK: [[IF_THEN]]: ; CHECK-NEXT: [[VAL:%.*]] = or i32 [[X]], [[Y]] ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[VAL]], i32 2) ; CHECK-NEXT: ret i32 [[MAX]] ; CHECK: [[IF_ELSE]]: ; CHECK-NEXT: ret i32 0 ; %cond = icmp ne i32 %x, 0 br i1 %cond, label %if.then, label %if.else if.then: %val = or i32 %x, %y %max = call i32 @llvm.umax.i32(i32 %val, i32 2) ret i32 %max if.else: ret i32 0 } define i32 @unknown_by_and(i32 %x, i32 %y) { ; CHECK-LABEL: define i32 @unknown_by_and( ; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) { ; CHECK-NEXT: [[COND:%.*]] = icmp ne i32 [[X]], 0 ; CHECK-NEXT: br i1 [[COND]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]] ; CHECK: [[IF_THEN]]: ; CHECK-NEXT: [[VAL:%.*]] = and i32 [[X]], [[Y]] ; CHECK-NEXT: [[MAX:%.*]] = call i32 @llvm.umax.i32(i32 [[VAL]], i32 1) ; CHECK-NEXT: ret i32 [[MAX]] ; CHECK: [[IF_ELSE]]: ; CHECK-NEXT: ret i32 0 ; %cond = icmp ne i32 %x, 0 br i1 %cond, label %if.then, label %if.else if.then: %val = and i32 %x, %y %max = call i32 @llvm.umax.i32(i32 %val, i32 1) ret i32 %max if.else: ret i32 0 }