| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py |
| ; RUN: opt < %s -passes=instcombine -S | FileCheck %s |
| |
| declare void @use.i8(i8) |
| define i8 @test_add_nsw(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_add_nsw( |
| ; CHECK-NEXT: [[LHS:%.*]] = add nsw i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = add nsw i8 [[X]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub nsw i8 [[Y]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = add nsw i8 %x, %y |
| %rhs = add nsw i8 %x, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = sub nsw i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_add_nsw_no_prop(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_add_nsw_no_prop( |
| ; CHECK-NEXT: [[LHS:%.*]] = add nsw i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = add nuw i8 [[X]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub i8 [[Y]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = add nsw i8 %x, %y |
| %rhs = add nuw i8 %x, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = sub nsw i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_add(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_add( |
| ; CHECK-NEXT: [[LHS:%.*]] = add i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = add i8 [[X]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub i8 [[Y]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = add i8 %x, %y |
| %rhs = add i8 %x, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = sub i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_add_fail(i8 %w, i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_add_fail( |
| ; CHECK-NEXT: [[LHS:%.*]] = add i8 [[W:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = add i8 [[X:%.*]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub i8 [[LHS]], [[RHS]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = add i8 %w, %y |
| %rhs = add i8 %x, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = sub i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_add_nuw(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_add_nuw( |
| ; CHECK-NEXT: [[LHS:%.*]] = add i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = or disjoint i8 [[X]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub nuw i8 [[Y]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = add i8 %x, %y |
| %rhs = or disjoint i8 %x, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = sub nuw i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_add_nuw_no_prop(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_add_nuw_no_prop( |
| ; CHECK-NEXT: [[LHS:%.*]] = add i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = or disjoint i8 [[X]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub i8 [[Y]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = add i8 %x, %y |
| %rhs = or disjoint i8 %x, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = sub i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_sub_nuw(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_sub_nuw( |
| ; CHECK-NEXT: [[LHS:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = sub nuw i8 [[Y]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub nuw i8 [[X]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = sub nuw i8 %x, %y |
| %rhs = sub nuw i8 %y, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = add i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_sub_nuw_no_prop(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_sub_nuw_no_prop( |
| ; CHECK-NEXT: [[LHS:%.*]] = sub nuw i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = sub i8 [[Y]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub i8 [[X]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = sub nuw i8 %x, %y |
| %rhs = sub i8 %y, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = add nuw i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_sub_nsw(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_sub_nsw( |
| ; CHECK-NEXT: [[LHS:%.*]] = sub nsw i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = sub nsw i8 [[Y]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub nsw i8 [[X]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = sub nsw i8 %x, %y |
| %rhs = sub nsw i8 %y, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = or disjoint i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_sub_nsw_no_prop(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_sub_nsw_no_prop( |
| ; CHECK-NEXT: [[LHS:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = sub nsw i8 [[Y]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub i8 [[X]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = sub i8 %x, %y |
| %rhs = sub nsw i8 %y, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = or disjoint i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_sub_none(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_sub_none( |
| ; CHECK-NEXT: [[LHS:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = sub i8 [[Y]], [[Z:%.*]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = sub i8 [[X]], [[Z]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = sub i8 %x, %y |
| %rhs = sub i8 %y, %z |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = add i8 %lhs, %rhs |
| ret i8 %r |
| } |
| |
| define i8 @test_sub_none_fail(i8 %x, i8 %y, i8 %z) { |
| ; CHECK-LABEL: @test_sub_none_fail( |
| ; CHECK-NEXT: [[LHS:%.*]] = sub i8 [[X:%.*]], [[Y:%.*]] |
| ; CHECK-NEXT: [[RHS:%.*]] = sub i8 [[Z:%.*]], [[Y]] |
| ; CHECK-NEXT: call void @use.i8(i8 [[LHS]]) |
| ; CHECK-NEXT: call void @use.i8(i8 [[RHS]]) |
| ; CHECK-NEXT: [[R:%.*]] = add i8 [[LHS]], [[RHS]] |
| ; CHECK-NEXT: ret i8 [[R]] |
| ; |
| %lhs = sub i8 %x, %y |
| %rhs = sub i8 %z, %y |
| call void @use.i8(i8 %lhs) |
| call void @use.i8(i8 %rhs) |
| %r = add i8 %lhs, %rhs |
| ret i8 %r |
| } |