1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt < %s -passes=div-rem-pairs -S -mtriple=amdgcn-amd-amdhsa | FileCheck %s 3 4define i32 @basic(ptr %p, i32 %x, i32 %y) { 5; CHECK-LABEL: define i32 @basic( 6; CHECK-SAME: ptr [[P:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) { 7; CHECK-NEXT: [[X_FROZEN:%.*]] = freeze i32 [[X]] 8; CHECK-NEXT: [[Y_FROZEN:%.*]] = freeze i32 [[Y]] 9; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[X_FROZEN]], [[Y_FROZEN]] 10; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], [[Y_FROZEN]] 11; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[X_FROZEN]], [[TMP1]] 12; CHECK-NEXT: store i32 [[DIV]], ptr [[P]], align 4 13; CHECK-NEXT: ret i32 [[REM_DECOMPOSED]] 14; 15 %div = udiv i32 %x, %y 16 %rem = urem i32 %x, %y 17 store i32 %div, ptr %p, align 4 18 ret i32 %rem 19} 20 21define i32 @no_freezes(ptr %p, i32 noundef %x, i32 noundef %y) { 22; CHECK-LABEL: define i32 @no_freezes( 23; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) { 24; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[X]], [[Y]] 25; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], [[Y]] 26; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[X]], [[TMP1]] 27; CHECK-NEXT: store i32 [[DIV]], ptr [[P]], align 4 28; CHECK-NEXT: ret i32 [[REM_DECOMPOSED]] 29; 30 %div = udiv i32 %x, %y 31 %rem = urem i32 %x, %y 32 store i32 %div, ptr %p, align 4 33 ret i32 %rem 34} 35 36define i32 @poison_does_not_freeze(ptr %p, i32 noundef %x, i32 noundef %y) { 37; CHECK-LABEL: define i32 @poison_does_not_freeze( 38; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) { 39; CHECK-NEXT: [[X2:%.*]] = shl nuw nsw i32 [[X]], 5 40; CHECK-NEXT: [[Y2:%.*]] = add nuw nsw i32 [[Y]], 1 41; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[X2]], [[Y2]] 42; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], [[Y2]] 43; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[X2]], [[TMP1]] 44; CHECK-NEXT: store i32 [[DIV]], ptr [[P]], align 4 45; CHECK-NEXT: ret i32 [[REM_DECOMPOSED]] 46; 47 %x2 = shl nuw nsw i32 %x, 5 48 %y2 = add nuw nsw i32 %y, 1 49 %div = udiv i32 %x2, %y2 50 %rem = urem i32 %x2, %y2 51 store i32 %div, ptr %p, align 4 52 ret i32 %rem 53} 54 55define i32 @poison_does_not_freeze_signed(ptr %p, i32 noundef %x, i32 noundef %y) { 56; CHECK-LABEL: define i32 @poison_does_not_freeze_signed( 57; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) { 58; CHECK-NEXT: [[X2:%.*]] = shl nuw nsw i32 [[X]], 5 59; CHECK-NEXT: [[Y2:%.*]] = add nuw nsw i32 [[Y]], 1 60; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X2]], [[Y2]] 61; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], [[Y2]] 62; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[X2]], [[TMP1]] 63; CHECK-NEXT: store i32 [[DIV]], ptr [[P]], align 4 64; CHECK-NEXT: ret i32 [[REM_DECOMPOSED]] 65; 66 %x2 = shl nuw nsw i32 %x, 5 67 %y2 = add nuw nsw i32 %y, 1 68 %div = sdiv i32 %x2, %y2 69 %rem = srem i32 %x2, %y2 70 store i32 %div, ptr %p, align 4 71 ret i32 %rem 72} 73 74define <4 x i8> @poison_does_not_freeze_vector(ptr %p, <4 x i8> noundef %x, <4 x i8> noundef %y) { 75; CHECK-LABEL: define <4 x i8> @poison_does_not_freeze_vector( 76; CHECK-SAME: ptr [[P:%.*]], <4 x i8> noundef [[X:%.*]], <4 x i8> noundef [[Y:%.*]]) { 77; CHECK-NEXT: [[X2:%.*]] = shl nuw nsw <4 x i8> [[X]], splat (i8 5) 78; CHECK-NEXT: [[Y2:%.*]] = add nuw nsw <4 x i8> [[Y]], splat (i8 1) 79; CHECK-NEXT: [[DIV:%.*]] = udiv <4 x i8> [[X2]], [[Y2]] 80; CHECK-NEXT: [[TMP1:%.*]] = mul <4 x i8> [[DIV]], [[Y2]] 81; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub <4 x i8> [[X2]], [[TMP1]] 82; CHECK-NEXT: store <4 x i8> [[DIV]], ptr [[P]], align 4 83; CHECK-NEXT: ret <4 x i8> [[REM_DECOMPOSED]] 84; 85 %x2 = shl nuw nsw <4 x i8> %x, <i8 5, i8 5, i8 5, i8 5> 86 %y2 = add nuw nsw <4 x i8> %y, <i8 1, i8 1, i8 1, i8 1> 87 %div = udiv <4 x i8> %x2, %y2 88 %rem = urem <4 x i8> %x2, %y2 89 store <4 x i8> %div, ptr %p, align 4 90 ret <4 x i8> %rem 91} 92 93define i32 @explicit_poison_does_not_freeze(ptr %p, i32 noundef %y) { 94; CHECK-LABEL: define i32 @explicit_poison_does_not_freeze( 95; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[Y:%.*]]) { 96; CHECK-NEXT: [[X:%.*]] = add i32 poison, 1 97; CHECK-NEXT: [[Y2:%.*]] = add nuw nsw i32 [[Y]], 1 98; CHECK-NEXT: [[DIV:%.*]] = udiv i32 [[X]], [[Y2]] 99; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], [[Y2]] 100; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[X]], [[TMP1]] 101; CHECK-NEXT: store i32 [[DIV]], ptr [[P]], align 4 102; CHECK-NEXT: ret i32 [[REM_DECOMPOSED]] 103; 104 %x = add i32 poison, 1 105 %y2 = add nuw nsw i32 %y, 1 106 %div = udiv i32 %x, %y2 107 %rem = urem i32 %x, %y2 108 store i32 %div, ptr %p, align 4 109 ret i32 %rem 110} 111 112define i32 @explicit_poison_does_not_freeze_signed(ptr %p, i32 noundef %y) { 113; CHECK-LABEL: define i32 @explicit_poison_does_not_freeze_signed( 114; CHECK-SAME: ptr [[P:%.*]], i32 noundef [[Y:%.*]]) { 115; CHECK-NEXT: [[X:%.*]] = add i32 poison, 1 116; CHECK-NEXT: [[Y2:%.*]] = add nuw nsw i32 [[Y]], 1 117; CHECK-NEXT: [[DIV:%.*]] = sdiv i32 [[X]], [[Y2]] 118; CHECK-NEXT: [[TMP1:%.*]] = mul i32 [[DIV]], [[Y2]] 119; CHECK-NEXT: [[REM_DECOMPOSED:%.*]] = sub i32 [[X]], [[TMP1]] 120; CHECK-NEXT: store i32 [[DIV]], ptr [[P]], align 4 121; CHECK-NEXT: ret i32 [[REM_DECOMPOSED]] 122; 123 %x = add i32 poison, 1 124 %y2 = add nuw nsw i32 %y, 1 125 %div = sdiv i32 %x, %y2 126 %rem = srem i32 %x, %y2 127 store i32 %div, ptr %p, align 4 128 ret i32 %rem 129} 130