; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt < %s -passes=instcombine -S | FileCheck %s define @binop_reverse_elim( %a, %b, i32 %evl) { ; CHECK-LABEL: @binop_reverse_elim( ; CHECK-NEXT: [[ADD1:%.*]] = add nsw [[A:%.*]], [[B:%.*]] ; CHECK-NEXT: ret [[ADD1]] ; %a.rev = tail call @llvm.experimental.vp.reverse( %a, splat (i1 true), i32 %evl) %b.rev = tail call @llvm.experimental.vp.reverse( %b, splat (i1 true), i32 %evl) %add = add nsw %a.rev, %b.rev %add.rev = tail call @llvm.experimental.vp.reverse( %add, splat (i1 true), i32 %evl) ret %add.rev } ; Negative test - the mask needs to be reversed between the inner and ; the outer to be correct. define @binop_reverse_elim_samemask( %a, %b, %m, i32 %evl) { ; CHECK-LABEL: @binop_reverse_elim_samemask( ; CHECK-NEXT: [[A_REV:%.*]] = tail call @llvm.experimental.vp.reverse.nxv4i32( [[A:%.*]], [[M:%.*]], i32 [[EVL:%.*]]) ; CHECK-NEXT: [[B_REV:%.*]] = tail call @llvm.experimental.vp.reverse.nxv4i32( [[B:%.*]], [[M]], i32 [[EVL]]) ; CHECK-NEXT: [[ADD:%.*]] = add nsw [[A_REV]], [[B_REV]] ; CHECK-NEXT: [[ADD_REV:%.*]] = tail call @llvm.experimental.vp.reverse.nxv4i32( [[ADD]], [[M]], i32 [[EVL]]) ; CHECK-NEXT: ret [[ADD_REV]] ; %a.rev = tail call @llvm.experimental.vp.reverse( %a, %m, i32 %evl) %b.rev = tail call @llvm.experimental.vp.reverse( %b, %m, i32 %evl) %add = add nsw %a.rev, %b.rev %add.rev = tail call @llvm.experimental.vp.reverse( %add, %m, i32 %evl) ret %add.rev } define @binop_reverse_elim_diffmask( %a, %b, %m1, %m2, i32 %evl) { ; CHECK-LABEL: @binop_reverse_elim_diffmask( ; CHECK-NEXT: [[A_REV:%.*]] = tail call @llvm.experimental.vp.reverse.nxv4i32( [[A:%.*]], [[M1:%.*]], i32 [[EVL:%.*]]) ; CHECK-NEXT: [[B_REV:%.*]] = tail call @llvm.experimental.vp.reverse.nxv4i32( [[B:%.*]], [[M1]], i32 [[EVL]]) ; CHECK-NEXT: [[ADD:%.*]] = add nsw [[A_REV]], [[B_REV]] ; CHECK-NEXT: [[ADD_REV:%.*]] = tail call @llvm.experimental.vp.reverse.nxv4i32( [[ADD]], [[M2:%.*]], i32 10) ; CHECK-NEXT: ret [[ADD_REV]] ; %a.rev = tail call @llvm.experimental.vp.reverse( %a, %m1, i32 %evl) %b.rev = tail call @llvm.experimental.vp.reverse( %b, %m1, i32 %evl) %add = add nsw %a.rev, %b.rev %add.rev = tail call @llvm.experimental.vp.reverse( %add, %m2, i32 10) ret %add.rev } define @binop_reverse_elim_diffevl( %a, %b, i32 %evl) { ; CHECK-LABEL: @binop_reverse_elim_diffevl( ; CHECK-NEXT: [[ADD:%.*]] = add nsw [[A_REV:%.*]], [[B_REV:%.*]] ; CHECK-NEXT: [[ADD1:%.*]] = call @llvm.experimental.vp.reverse.nxv4i32( [[ADD]], splat (i1 true), i32 [[EVL:%.*]]) ; CHECK-NEXT: [[ADD_REV:%.*]] = tail call @llvm.experimental.vp.reverse.nxv4i32( [[ADD1]], splat (i1 true), i32 10) ; CHECK-NEXT: ret [[ADD_REV]] ; %a.rev = tail call @llvm.experimental.vp.reverse( %a, splat (i1 true), i32 %evl) %b.rev = tail call @llvm.experimental.vp.reverse( %b, splat (i1 true), i32 %evl) %add = add nsw %a.rev, %b.rev %add.rev = tail call @llvm.experimental.vp.reverse( %add, splat (i1 true), i32 10) ret %add.rev } define @binop_reverse_splat_elim( %a, i32 %evl) { ; CHECK-LABEL: @binop_reverse_splat_elim( ; CHECK-NEXT: [[ADD1:%.*]] = add nsw [[A:%.*]], splat (i32 22) ; CHECK-NEXT: ret [[ADD1]] ; %a.rev = tail call @llvm.experimental.vp.reverse( %a, splat (i1 true), i32 %evl) %add = add nsw %a.rev, splat (i32 22) %add.rev = tail call @llvm.experimental.vp.reverse( %add, splat (i1 true), i32 %evl) ret %add.rev } define @binop_reverse_splat_elim2( %a, i32 %evl) { ; CHECK-LABEL: @binop_reverse_splat_elim2( ; CHECK-NEXT: [[ADD1:%.*]] = add nsw [[A:%.*]], splat (i32 22) ; CHECK-NEXT: ret [[ADD1]] ; %a.rev = tail call @llvm.experimental.vp.reverse( %a, splat (i1 true), i32 %evl) %add = add nsw splat (i32 22), %a.rev %add.rev = tail call @llvm.experimental.vp.reverse( %add, splat (i1 true), i32 %evl) ret %add.rev } define @binop_reverse_splat_elim3( %a, i32 %b, i32 %evl) { ; CHECK-LABEL: @binop_reverse_splat_elim3( ; CHECK-NEXT: [[B_INS:%.*]] = insertelement poison, i32 [[B:%.*]], i64 0 ; CHECK-NEXT: [[B_VEC:%.*]] = shufflevector [[B_INS]], poison, zeroinitializer ; CHECK-NEXT: [[ADD:%.*]] = add nsw [[B_VEC]], [[A_REV:%.*]] ; CHECK-NEXT: ret [[ADD]] ; %b.ins = insertelement poison, i32 %b, i32 0 %b.vec = shufflevector %b.ins, poison, zeroinitializer %a.rev = tail call @llvm.experimental.vp.reverse( %a, splat (i1 true), i32 %evl) %add = add nsw %b.vec, %a.rev %add.rev = tail call @llvm.experimental.vp.reverse( %add, splat (i1 true), i32 %evl) ret %add.rev } define @binop_reverse_splat_elim4( %a, i32 %b, i32 %evl) { ; CHECK-LABEL: @binop_reverse_splat_elim4( ; CHECK-NEXT: [[B_INS:%.*]] = insertelement poison, i32 [[B:%.*]], i64 0 ; CHECK-NEXT: [[B_VEC:%.*]] = shufflevector [[B_INS]], poison, zeroinitializer ; CHECK-NEXT: [[ADD1:%.*]] = add nsw [[A:%.*]], [[B_VEC]] ; CHECK-NEXT: ret [[ADD1]] ; %b.ins = insertelement poison, i32 %b, i32 0 %b.vec = shufflevector %b.ins, poison, zeroinitializer %a.rev = tail call @llvm.experimental.vp.reverse( %a, splat (i1 true), i32 %evl) %add = add nsw %a.rev, %b.vec %add.rev = tail call @llvm.experimental.vp.reverse( %add, splat (i1 true), i32 %evl) ret %add.rev } define @unop_reverse_splat_elim( %a, %b, i32 %evl) { ; CHECK-LABEL: @unop_reverse_splat_elim( ; CHECK-NEXT: [[OP:%.*]] = fneg [[A_REV:%.*]] ; CHECK-NEXT: ret [[OP]] ; %a.rev = tail call @llvm.experimental.vp.reverse.nxv4f32( %a, splat (i1 true), i32 %evl) %op = fneg %a.rev %op.rev = tail call @llvm.experimental.vp.reverse.nxv4f32( %op, splat (i1 true), i32 %evl) ret %op.rev }