; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 ; RUN: opt -p hexagon-loop-idiom -S < %s | FileCheck %s target triple = "hexagon" ; There need to be two pmpy instructions. define zeroext i16 @pmpy_trunc(i8 zeroext %a0, i16 zeroext %a1) local_unnamed_addr { ; CHECK-LABEL: define zeroext i16 @pmpy_trunc( ; CHECK-SAME: i8 zeroext [[A0:%.*]], i16 zeroext [[A1:%.*]]) local_unnamed_addr { ; CHECK-NEXT: [[B1:.*]]: ; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[A1]] to i32 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A0]] to i32 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP0]], [[TMP1]] ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 255 ; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.hexagon.M4.pmpyw(i32 [[TMP3]], i32 255) ; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32 ; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 255 ; CHECK-NEXT: [[TMP7:%.*]] = call i64 @llvm.hexagon.M4.pmpyw(i32 [[TMP6]], i32 81922) ; CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP2]] to i64 ; CHECK-NEXT: [[TMP9:%.*]] = xor i64 [[TMP7]], [[TMP8]] ; CHECK-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32 ; CHECK-NEXT: br label %[[B2:.*]] ; CHECK: [[B2]]: ; CHECK-NEXT: [[PHI1:%.*]] = phi i32 [ 0, %[[B1]] ], [ [[ADD:%.*]], %[[B2]] ] ; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ [[TMP0]], %[[B1]] ], [ [[TMP10]], %[[B2]] ] ; CHECK-NEXT: [[TMP11:%.*]] = xor i32 [[PHI2]], [[TMP1]] ; CHECK-NEXT: [[TMP12:%.*]] = shl i32 1, [[PHI1]] ; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP11]], [[TMP12]] ; CHECK-NEXT: [[TMP14:%.*]] = icmp ne i32 [[TMP13]], 0 ; CHECK-NEXT: [[TMP15:%.*]] = shl i32 81922, [[PHI1]] ; CHECK-NEXT: [[TMP16:%.*]] = xor i32 [[PHI2]], [[TMP15]] ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[PHI1]], 1 ; CHECK-NEXT: [[ICMP:%.*]] = icmp samesign ult i32 [[PHI1]], 7 ; CHECK-NEXT: br i1 [[ICMP]], label %[[B2]], label %[[B3:.*]] ; CHECK: [[B3]]: ; CHECK-NEXT: [[SELECT_LCSSA:%.*]] = phi i32 [ [[TMP10]], %[[B2]] ] ; CHECK-NEXT: [[TMP17:%.*]] = lshr i32 [[SELECT_LCSSA]], 8 ; CHECK-NEXT: [[TMP18:%.*]] = trunc i32 [[TMP17]] to i16 ; CHECK-NEXT: ret i16 [[TMP18]] ; b1: br label %b2 b2: ; preds = %b1, %b2 %phi1 = phi i8 [ 0, %b1 ], [ %add, %b2 ] %phi2 = phi i16 [ %a1, %b1 ], [ %select, %b2 ] %phi3 = phi i8 [ %a0, %b1 ], [ %lshr1, %b2 ] %trunc1 = trunc i16 %phi2 to i8 %xor1 = xor i8 %phi3, %trunc1 %lshr1 = lshr i8 %phi3, 1 %trunc2 = trunc i8 %xor1 to i1 %lshr2 = lshr i16 %phi2, 1 %xor2 = xor i16 %lshr2, -24575 %select = select i1 %trunc2, i16 %xor2, i16 %lshr2 %add = add nuw nsw i8 %phi1, 1 %icmp = icmp samesign ult i8 %phi1, 7 br i1 %icmp, label %b2, label %b3 b3: ; preds = %b2 %select.lcssa = phi i16 [ %select, %b2 ] ret i16 %select.lcssa } ; There need to be two pmpy instructions. define zeroext i16 @pmpy_trunc_not(i8 zeroext %a0, i16 zeroext %a1) local_unnamed_addr { ; CHECK-LABEL: define zeroext i16 @pmpy_trunc_not( ; CHECK-SAME: i8 zeroext [[A0:%.*]], i16 zeroext [[A1:%.*]]) local_unnamed_addr { ; CHECK-NEXT: [[B1:.*]]: ; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[A1]] to i32 ; CHECK-NEXT: [[TMP1:%.*]] = zext i8 [[A0]] to i32 ; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP0]], [[TMP1]] ; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[TMP2]], 255 ; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.hexagon.M4.pmpyw(i32 [[TMP3]], i32 255) ; CHECK-NEXT: [[TMP5:%.*]] = trunc i64 [[TMP4]] to i32 ; CHECK-NEXT: [[TMP6:%.*]] = and i32 [[TMP5]], 255 ; CHECK-NEXT: [[TMP7:%.*]] = call i64 @llvm.hexagon.M4.pmpyw(i32 [[TMP6]], i32 81922) ; CHECK-NEXT: [[TMP8:%.*]] = zext i32 [[TMP2]] to i64 ; CHECK-NEXT: [[TMP9:%.*]] = xor i64 [[TMP7]], [[TMP8]] ; CHECK-NEXT: [[TMP10:%.*]] = trunc i64 [[TMP9]] to i32 ; CHECK-NEXT: br label %[[B2:.*]] ; CHECK: [[B2]]: ; CHECK-NEXT: [[PHI1:%.*]] = phi i32 [ 0, %[[B1]] ], [ [[ADD:%.*]], %[[B2]] ] ; CHECK-NEXT: [[PHI2:%.*]] = phi i32 [ [[TMP0]], %[[B1]] ], [ [[TMP10]], %[[B2]] ] ; CHECK-NEXT: [[TMP11:%.*]] = xor i32 [[PHI2]], [[TMP1]] ; CHECK-NEXT: [[TMP12:%.*]] = shl i32 1, [[PHI1]] ; CHECK-NEXT: [[TMP13:%.*]] = and i32 [[TMP11]], [[TMP12]] ; CHECK-NEXT: [[TMP14:%.*]] = icmp eq i32 [[TMP13]], 0 ; CHECK-NEXT: [[TMP15:%.*]] = shl i32 81922, [[PHI1]] ; CHECK-NEXT: [[TMP16:%.*]] = xor i32 [[PHI2]], [[TMP15]] ; CHECK-NEXT: [[ADD]] = add nuw nsw i32 [[PHI1]], 1 ; CHECK-NEXT: [[ICMP:%.*]] = icmp samesign ult i32 [[PHI1]], 7 ; CHECK-NEXT: br i1 [[ICMP]], label %[[B2]], label %[[B3:.*]] ; CHECK: [[B3]]: ; CHECK-NEXT: [[SELECT_LCSSA1:%.*]] = phi i32 [ [[TMP10]], %[[B2]] ] ; CHECK-NEXT: [[TMP17:%.*]] = lshr i32 [[SELECT_LCSSA1]], 8 ; CHECK-NEXT: [[SELECT_LCSSA:%.*]] = trunc i32 [[TMP17]] to i16 ; CHECK-NEXT: ret i16 [[SELECT_LCSSA]] ; b1: br label %b2 b2: ; preds = %b1, %b2 %phi1 = phi i8 [ 0, %b1 ], [ %add, %b2 ] %phi2 = phi i16 [ %a1, %b1 ], [ %select, %b2 ] %phi3 = phi i8 [ %a0, %b1 ], [ %lshr1, %b2 ] %trunc1 = trunc i16 %phi2 to i8 %xor1 = xor i8 %phi3, %trunc1 %lshr1 = lshr i8 %phi3, 1 %trunc2 = trunc i8 %xor1 to i1 %not = xor i1 %trunc2, true %lshr2 = lshr i16 %phi2, 1 %xor2 = xor i16 %lshr2, -24575 %select = select i1 %not, i16 %lshr2, i16 %xor2 %add = add nuw nsw i8 %phi1, 1 %icmp = icmp samesign ult i8 %phi1, 7 br i1 %icmp, label %b2, label %b3 b3: ; preds = %b2 %select.lcssa = phi i16 [ %select, %b2 ] ret i16 %select.lcssa }