1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -gvn -S < %s | FileCheck %s 3 4declare void @use(i32, i32) 5 6define void @binop(i32 %x, i32 %y) { 7; CHECK-LABEL: @binop( 8; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], [[Y:%.*]] 9; CHECK-NEXT: call void @use(i32 [[ADD1]], i32 [[ADD1]]) 10; CHECK-NEXT: ret void 11; 12 %add1 = add i32 %x, %y 13 %add2 = add i32 %y, %x 14 call void @use(i32 %add1, i32 %add2) 15 ret void 16} 17 18declare void @vse(i1, i1) 19 20define void @cmp(i32 %x, i32 %y) { 21; CHECK-LABEL: @cmp( 22; CHECK-NEXT: [[CMP1:%.*]] = icmp ult i32 [[X:%.*]], [[Y:%.*]] 23; CHECK-NEXT: call void @vse(i1 [[CMP1]], i1 [[CMP1]]) 24; CHECK-NEXT: ret void 25; 26 %cmp1 = icmp ult i32 %x, %y 27 %cmp2 = icmp ugt i32 %y, %x 28 call void @vse(i1 %cmp1, i1 %cmp2) 29 ret void 30} 31 32declare i32 @llvm.umax.i32(i32, i32) 33 34define void @intrinsic(i32 %x, i32 %y) { 35; CHECK-LABEL: @intrinsic( 36; CHECK-NEXT: [[M1:%.*]] = call i32 @llvm.umax.i32(i32 [[X:%.*]], i32 [[Y:%.*]]) 37; CHECK-NEXT: call void @use(i32 [[M1]], i32 [[M1]]) 38; CHECK-NEXT: ret void 39; 40 %m1 = call i32 @llvm.umax.i32(i32 %x, i32 %y) 41 %m2 = call i32 @llvm.umax.i32(i32 %y, i32 %x) 42 call void @use(i32 %m1, i32 %m2) 43 ret void 44} 45 46declare { i32, i1 } @llvm.umul.with.overflow.i32(i32, i32) 47 48define { i32, i1 } @intrinsic2(i32 %x, i32 %y, i1 %cond) { 49; CHECK-LABEL: @intrinsic2( 50; CHECK-NEXT: entry: 51; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 52; CHECK: if.then: 53; CHECK-NEXT: unreachable 54; CHECK: if.end: 55; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 0, [[Y:%.*]] 56; CHECK-NEXT: [[UMUL:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[X:%.*]], i32 [[Y]]) 57; CHECK-NEXT: ret { i32, i1 } [[UMUL]] 58; 59entry: 60 br i1 %cond, label %if.then, label %if.end 61 62if.then: 63 unreachable 64 65if.end: 66 %cmp = icmp eq i32 0, %y 67 %umul = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %x, i32 %y) 68 ret { i32, i1 } %umul 69} 70 71declare i16 @llvm.smul.fix.i16(i16, i16, i32) 72declare i16 @llvm.umul.fix.i16(i16, i16, i32) 73 74define i16 @intrinsic_3_args(i16 %x, i16 %y) { 75; CHECK-LABEL: @intrinsic_3_args( 76; CHECK-NEXT: [[M1:%.*]] = call i16 @llvm.smul.fix.i16(i16 [[X:%.*]], i16 [[Y:%.*]], i32 1) 77; CHECK-NEXT: ret i16 0 78; 79 %m1 = call i16 @llvm.smul.fix.i16(i16 %x, i16 %y, i32 1) 80 %m2 = call i16 @llvm.smul.fix.i16(i16 %y, i16 %x, i32 1) 81 %r = sub i16 %m1, %m2 82 ret i16 %r 83} 84 85; Negative test - 3rd arg is different 86 87define i16 @intrinsic_3_args_not_same(i16 %x, i16 %y) { 88; CHECK-LABEL: @intrinsic_3_args_not_same( 89; CHECK-NEXT: [[M1:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[X:%.*]], i16 [[Y:%.*]], i32 2) 90; CHECK-NEXT: [[M2:%.*]] = call i16 @llvm.umul.fix.i16(i16 [[Y]], i16 [[X]], i32 1) 91; CHECK-NEXT: [[R:%.*]] = sub i16 [[M1]], [[M2]] 92; CHECK-NEXT: ret i16 [[R]] 93; 94 %m1 = call i16 @llvm.umul.fix.i16(i16 %x, i16 %y, i32 2) 95 %m2 = call i16 @llvm.umul.fix.i16(i16 %y, i16 %x, i32 1) 96 %r = sub i16 %m1, %m2 97 ret i16 %r 98} 99 100declare float @llvm.fma.f32(float, float, float) 101 102define float @fma(float %x, float %y) { 103; CHECK-LABEL: @fma( 104; CHECK-NEXT: [[M1:%.*]] = call float @llvm.fma.f32(float [[X:%.*]], float [[Y:%.*]], float 1.000000e+00) 105; CHECK-NEXT: ret float 1.000000e+00 106; 107 %m1 = call float @llvm.fma.f32(float %x, float %y, float 1.0) 108 %m2 = call float @llvm.fma.f32(float %y, float %x, float 1.0) 109 %r = fdiv nnan float %m1, %m2 110 ret float %r 111} 112