1*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-linux | FileCheck %s 2*9880d681SAndroid Build Coastguard Worker; RUN: llc < %s -mtriple=x86_64-win64 | FileCheck %s 3*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S | FileCheck %s --check-prefix=OPTALL --check-prefix=OPT --check-prefix=NONSTRESS 4*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S -stress-cgp-ext-ld-promotion | FileCheck %s --check-prefix=OPTALL --check-prefix=OPT --check-prefix=STRESS 5*9880d681SAndroid Build Coastguard Worker; RUN: opt -codegenprepare < %s -mtriple=x86_64-apple-macosx -S -disable-cgp-ext-ld-promotion | FileCheck %s --check-prefix=OPTALL --check-prefix=DISABLE 6*9880d681SAndroid Build Coastguard Worker 7*9880d681SAndroid Build Coastguard Worker; rdar://7304838 8*9880d681SAndroid Build Coastguard Worker; CodeGenPrepare should move the zext into the block with the load 9*9880d681SAndroid Build Coastguard Worker; so that SelectionDAG can select it with the load. 10*9880d681SAndroid Build Coastguard Worker; 11*9880d681SAndroid Build Coastguard Worker; CHECK-LABEL: foo: 12*9880d681SAndroid Build Coastguard Worker; CHECK: movsbl ({{%rdi|%rcx}}), %eax 13*9880d681SAndroid Build Coastguard Worker; 14*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @foo 15*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 16*9880d681SAndroid Build Coastguard Worker; OPTALL-NEXT: [[ZEXT:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32 17*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[ZEXT]], i32* %q 18*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 19*9880d681SAndroid Build Coastguard Workerdefine void @foo(i8* %p, i32* %q) { 20*9880d681SAndroid Build Coastguard Workerentry: 21*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 22*9880d681SAndroid Build Coastguard Worker %a = icmp slt i8 %t, 20 23*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 24*9880d681SAndroid Build Coastguard Workertrue: 25*9880d681SAndroid Build Coastguard Worker %s = zext i8 %t to i32 26*9880d681SAndroid Build Coastguard Worker store i32 %s, i32* %q 27*9880d681SAndroid Build Coastguard Worker ret void 28*9880d681SAndroid Build Coastguard Workerfalse: 29*9880d681SAndroid Build Coastguard Worker ret void 30*9880d681SAndroid Build Coastguard Worker} 31*9880d681SAndroid Build Coastguard Worker 32*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a zextload is an operation with only one 33*9880d681SAndroid Build Coastguard Worker; argument to explicitly extend is in the way. 34*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteOneArg 35*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 36*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXT:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32 37*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT]], 2 38*9880d681SAndroid Build Coastguard Worker; Make sure the operation is not promoted when the promotion pass is disabled. 39*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], 2 40*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32 41*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q 42*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 43*9880d681SAndroid Build Coastguard Workerdefine void @promoteOneArg(i8* %p, i32* %q) { 44*9880d681SAndroid Build Coastguard Workerentry: 45*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 46*9880d681SAndroid Build Coastguard Worker %add = add nuw i8 %t, 2 47*9880d681SAndroid Build Coastguard Worker %a = icmp slt i8 %t, 20 48*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 49*9880d681SAndroid Build Coastguard Workertrue: 50*9880d681SAndroid Build Coastguard Worker %s = zext i8 %add to i32 51*9880d681SAndroid Build Coastguard Worker store i32 %s, i32* %q 52*9880d681SAndroid Build Coastguard Worker ret void 53*9880d681SAndroid Build Coastguard Workerfalse: 54*9880d681SAndroid Build Coastguard Worker ret void 55*9880d681SAndroid Build Coastguard Worker} 56*9880d681SAndroid Build Coastguard Worker 57*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a sextload is an operation with only one 58*9880d681SAndroid Build Coastguard Worker; argument to explicitly extend is in the way. 59*9880d681SAndroid Build Coastguard Worker; Version with sext. 60*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteOneArgSExt 61*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 62*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXT:%[a-zA-Z_0-9-]+]] = sext i8 [[LD]] to i32 63*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[SEXT]], 2 64*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], 2 65*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32 66*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q 67*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 68*9880d681SAndroid Build Coastguard Workerdefine void @promoteOneArgSExt(i8* %p, i32* %q) { 69*9880d681SAndroid Build Coastguard Workerentry: 70*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 71*9880d681SAndroid Build Coastguard Worker %add = add nsw i8 %t, 2 72*9880d681SAndroid Build Coastguard Worker %a = icmp slt i8 %t, 20 73*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 74*9880d681SAndroid Build Coastguard Workertrue: 75*9880d681SAndroid Build Coastguard Worker %s = sext i8 %add to i32 76*9880d681SAndroid Build Coastguard Worker store i32 %s, i32* %q 77*9880d681SAndroid Build Coastguard Worker ret void 78*9880d681SAndroid Build Coastguard Workerfalse: 79*9880d681SAndroid Build Coastguard Worker ret void 80*9880d681SAndroid Build Coastguard Worker} 81*9880d681SAndroid Build Coastguard Worker 82*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a zextload is an operation with two 83*9880d681SAndroid Build Coastguard Worker; arguments to explicitly extend is in the way. 84*9880d681SAndroid Build Coastguard Worker; Extending %add will create two extensions: 85*9880d681SAndroid Build Coastguard Worker; 1. One for %b. 86*9880d681SAndroid Build Coastguard Worker; 2. One for %t. 87*9880d681SAndroid Build Coastguard Worker; #1 will not be removed as we do not know anything about %b. 88*9880d681SAndroid Build Coastguard Worker; #2 may not be merged with the load because %t is used in a comparison. 89*9880d681SAndroid Build Coastguard Worker; Since two extensions may be emitted in the end instead of one before the 90*9880d681SAndroid Build Coastguard Worker; transformation, the regular heuristic does not apply the optimization. 91*9880d681SAndroid Build Coastguard Worker; 92*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteTwoArgZext 93*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 94*9880d681SAndroid Build Coastguard Worker; 95*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32 96*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i8 %b to i32 97*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]] 98*9880d681SAndroid Build Coastguard Worker; 99*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b 100*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32 101*9880d681SAndroid Build Coastguard Worker; 102*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b 103*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32 104*9880d681SAndroid Build Coastguard Worker; 105*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q 106*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 107*9880d681SAndroid Build Coastguard Workerdefine void @promoteTwoArgZext(i8* %p, i32* %q, i8 %b) { 108*9880d681SAndroid Build Coastguard Workerentry: 109*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 110*9880d681SAndroid Build Coastguard Worker %add = add nuw i8 %t, %b 111*9880d681SAndroid Build Coastguard Worker %a = icmp slt i8 %t, 20 112*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 113*9880d681SAndroid Build Coastguard Workertrue: 114*9880d681SAndroid Build Coastguard Worker %s = zext i8 %add to i32 115*9880d681SAndroid Build Coastguard Worker store i32 %s, i32* %q 116*9880d681SAndroid Build Coastguard Worker ret void 117*9880d681SAndroid Build Coastguard Workerfalse: 118*9880d681SAndroid Build Coastguard Worker ret void 119*9880d681SAndroid Build Coastguard Worker} 120*9880d681SAndroid Build Coastguard Worker 121*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a sextload is an operation with two 122*9880d681SAndroid Build Coastguard Worker; arguments to explicitly extend is in the way. 123*9880d681SAndroid Build Coastguard Worker; Version with sext. 124*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteTwoArgSExt 125*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 126*9880d681SAndroid Build Coastguard Worker; 127*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[SEXTLD:%[a-zA-Z_0-9-]+]] = sext i8 [[LD]] to i32 128*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[SEXTB:%[a-zA-Z_0-9-]+]] = sext i8 %b to i32 129*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[SEXTLD]], [[SEXTB]] 130*9880d681SAndroid Build Coastguard Worker; 131*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], %b 132*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32 133*9880d681SAndroid Build Coastguard Worker; 134*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i8 [[LD]], %b 135*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i8 [[ADD]] to i32 136*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q 137*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 138*9880d681SAndroid Build Coastguard Workerdefine void @promoteTwoArgSExt(i8* %p, i32* %q, i8 %b) { 139*9880d681SAndroid Build Coastguard Workerentry: 140*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 141*9880d681SAndroid Build Coastguard Worker %add = add nsw i8 %t, %b 142*9880d681SAndroid Build Coastguard Worker %a = icmp slt i8 %t, 20 143*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 144*9880d681SAndroid Build Coastguard Workertrue: 145*9880d681SAndroid Build Coastguard Worker %s = sext i8 %add to i32 146*9880d681SAndroid Build Coastguard Worker store i32 %s, i32* %q 147*9880d681SAndroid Build Coastguard Worker ret void 148*9880d681SAndroid Build Coastguard Workerfalse: 149*9880d681SAndroid Build Coastguard Worker ret void 150*9880d681SAndroid Build Coastguard Worker} 151*9880d681SAndroid Build Coastguard Worker 152*9880d681SAndroid Build Coastguard Worker; Check that we do not a zextload if we need to introduce more than 153*9880d681SAndroid Build Coastguard Worker; one additional extension. 154*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteThreeArgZext 155*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 156*9880d681SAndroid Build Coastguard Worker; 157*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32 158*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i8 %b to i32 159*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[TMP:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]] 160*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTC:%[a-zA-Z_0-9-]+]] = zext i8 %c to i32 161*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[TMP]], [[ZEXTC]] 162*9880d681SAndroid Build Coastguard Worker; 163*9880d681SAndroid Build Coastguard Worker; NONSTRESS-NEXT: [[TMP:%[a-zA-Z_0-9-]+]] = add nuw i8 [[LD]], %b 164*9880d681SAndroid Build Coastguard Worker; NONSTRESS-NEXT: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 [[TMP]], %c 165*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32 166*9880d681SAndroid Build Coastguard Worker; 167*9880d681SAndroid Build Coastguard Worker; DISABLE: add nuw i8 168*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i8 169*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i8 [[ADD]] to i32 170*9880d681SAndroid Build Coastguard Worker; 171*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q 172*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 173*9880d681SAndroid Build Coastguard Workerdefine void @promoteThreeArgZext(i8* %p, i32* %q, i8 %b, i8 %c) { 174*9880d681SAndroid Build Coastguard Workerentry: 175*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 176*9880d681SAndroid Build Coastguard Worker %tmp = add nuw i8 %t, %b 177*9880d681SAndroid Build Coastguard Worker %add = add nuw i8 %tmp, %c 178*9880d681SAndroid Build Coastguard Worker %a = icmp slt i8 %t, 20 179*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 180*9880d681SAndroid Build Coastguard Workertrue: 181*9880d681SAndroid Build Coastguard Worker %s = zext i8 %add to i32 182*9880d681SAndroid Build Coastguard Worker store i32 %s, i32* %q 183*9880d681SAndroid Build Coastguard Worker ret void 184*9880d681SAndroid Build Coastguard Workerfalse: 185*9880d681SAndroid Build Coastguard Worker ret void 186*9880d681SAndroid Build Coastguard Worker} 187*9880d681SAndroid Build Coastguard Worker 188*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a zextload after promoting and merging 189*9880d681SAndroid Build Coastguard Worker; two extensions. 190*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteMergeExtArgZExt 191*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 192*9880d681SAndroid Build Coastguard Worker; 193*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32 194*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = zext i16 %b to i32 195*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXTLD]], [[ZEXTB]] 196*9880d681SAndroid Build Coastguard Worker; 197*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16 198*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i16 [[ZEXTLD]], %b 199*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = zext i16 [[ADD]] to i32 200*9880d681SAndroid Build Coastguard Worker; 201*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16 202*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw i16 [[ZEXTLD]], %b 203*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = zext i16 [[ADD]] to i32 204*9880d681SAndroid Build Coastguard Worker; 205*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q 206*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 207*9880d681SAndroid Build Coastguard Workerdefine void @promoteMergeExtArgZExt(i8* %p, i32* %q, i16 %b) { 208*9880d681SAndroid Build Coastguard Workerentry: 209*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 210*9880d681SAndroid Build Coastguard Worker %ext = zext i8 %t to i16 211*9880d681SAndroid Build Coastguard Worker %add = add nuw i16 %ext, %b 212*9880d681SAndroid Build Coastguard Worker %a = icmp slt i8 %t, 20 213*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 214*9880d681SAndroid Build Coastguard Workertrue: 215*9880d681SAndroid Build Coastguard Worker %s = zext i16 %add to i32 216*9880d681SAndroid Build Coastguard Worker store i32 %s, i32* %q 217*9880d681SAndroid Build Coastguard Worker ret void 218*9880d681SAndroid Build Coastguard Workerfalse: 219*9880d681SAndroid Build Coastguard Worker ret void 220*9880d681SAndroid Build Coastguard Worker} 221*9880d681SAndroid Build Coastguard Worker 222*9880d681SAndroid Build Coastguard Worker; Check that we manage to form a sextload after promoting and merging 223*9880d681SAndroid Build Coastguard Worker; two extensions. 224*9880d681SAndroid Build Coastguard Worker; Version with sext. 225*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteMergeExtArgSExt 226*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 227*9880d681SAndroid Build Coastguard Worker; 228*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32 229*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[ZEXTB:%[a-zA-Z_0-9-]+]] = sext i16 %b to i32 230*9880d681SAndroid Build Coastguard Worker; STRESS-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i32 [[ZEXTLD]], [[ZEXTB]] 231*9880d681SAndroid Build Coastguard Worker; 232*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16 233*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i16 [[ZEXTLD]], %b 234*9880d681SAndroid Build Coastguard Worker; NONSTRESS: [[RES:%[a-zA-Z_0-9-]+]] = sext i16 [[ADD]] to i32 235*9880d681SAndroid Build Coastguard Worker; 236*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ZEXTLD:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i16 237*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i16 [[ZEXTLD]], %b 238*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i16 [[ADD]] to i32 239*9880d681SAndroid Build Coastguard Worker; OPTALL: store i32 [[RES]], i32* %q 240*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 241*9880d681SAndroid Build Coastguard Workerdefine void @promoteMergeExtArgSExt(i8* %p, i32* %q, i16 %b) { 242*9880d681SAndroid Build Coastguard Workerentry: 243*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 244*9880d681SAndroid Build Coastguard Worker %ext = zext i8 %t to i16 245*9880d681SAndroid Build Coastguard Worker %add = add nsw i16 %ext, %b 246*9880d681SAndroid Build Coastguard Worker %a = icmp slt i8 %t, 20 247*9880d681SAndroid Build Coastguard Worker br i1 %a, label %true, label %false 248*9880d681SAndroid Build Coastguard Workertrue: 249*9880d681SAndroid Build Coastguard Worker %s = sext i16 %add to i32 250*9880d681SAndroid Build Coastguard Worker store i32 %s, i32* %q 251*9880d681SAndroid Build Coastguard Worker ret void 252*9880d681SAndroid Build Coastguard Workerfalse: 253*9880d681SAndroid Build Coastguard Worker ret void 254*9880d681SAndroid Build Coastguard Worker} 255*9880d681SAndroid Build Coastguard Worker 256*9880d681SAndroid Build Coastguard Worker; Check that we manage to catch all the extload opportunities that are exposed 257*9880d681SAndroid Build Coastguard Worker; by the different iterations of codegen prepare. 258*9880d681SAndroid Build Coastguard Worker; Moreover, check that we do not promote more than we need to. 259*9880d681SAndroid Build Coastguard Worker; Here is what is happening in this test (not necessarly in this order): 260*9880d681SAndroid Build Coastguard Worker; 1. We try to promote the operand of %sextadd. 261*9880d681SAndroid Build Coastguard Worker; a. This creates one sext of %ld2 and one of %zextld 262*9880d681SAndroid Build Coastguard Worker; b. The sext of %ld2 can be combine with %ld2, so we remove one sext but 263*9880d681SAndroid Build Coastguard Worker; introduced one. This is fine with the current heuristic: neutral. 264*9880d681SAndroid Build Coastguard Worker; => We have one zext of %zextld left and we created one sext of %ld2. 265*9880d681SAndroid Build Coastguard Worker; 2. We try to promote the operand of %sextaddza. 266*9880d681SAndroid Build Coastguard Worker; a. This creates one sext of %zexta and one of %zextld 267*9880d681SAndroid Build Coastguard Worker; b. The sext of %zexta does not lead to any load, it stays here, even if it 268*9880d681SAndroid Build Coastguard Worker; could have been combine with the zext of %a. 269*9880d681SAndroid Build Coastguard Worker; c. The sext of %zextld leads to %ld and can be combined with it. This is 270*9880d681SAndroid Build Coastguard Worker; done by promoting %zextld. This is fine with the current heuristic: 271*9880d681SAndroid Build Coastguard Worker; neutral. 272*9880d681SAndroid Build Coastguard Worker; => We have created a new zext of %ld and we created one sext of %zexta. 273*9880d681SAndroid Build Coastguard Worker; 3. We try to promote the operand of %sextaddb. 274*9880d681SAndroid Build Coastguard Worker; a. This creates one sext of %b and one of %zextld 275*9880d681SAndroid Build Coastguard Worker; b. The sext of %b is a dead-end, nothing to be done. 276*9880d681SAndroid Build Coastguard Worker; c. Same thing as 2.c. happens. 277*9880d681SAndroid Build Coastguard Worker; => We have created a new zext of %ld and we created one sext of %b. 278*9880d681SAndroid Build Coastguard Worker; 4. We try to promote the operand of the zext of %zextld introduced in #1. 279*9880d681SAndroid Build Coastguard Worker; a. Same thing as 2.c. happens. 280*9880d681SAndroid Build Coastguard Worker; b. %zextld does not have any other uses. It is dead coded. 281*9880d681SAndroid Build Coastguard Worker; => We have created a new zext of %ld and we removed a zext of %zextld and 282*9880d681SAndroid Build Coastguard Worker; a zext of %ld. 283*9880d681SAndroid Build Coastguard Worker; Currently we do not try to reuse existing extensions, so in the end we have 284*9880d681SAndroid Build Coastguard Worker; 3 identical zext of %ld. The extensions will be CSE'ed by SDag. 285*9880d681SAndroid Build Coastguard Worker; 286*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @severalPromotions 287*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %addr1 288*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXTLD1_1:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64 289*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXTLD1_2:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64 290*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXTLD1_3:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64 291*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[LD2:%[a-zA-Z_0-9-]+]] = load i32, i32* %addr2 292*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXTLD2:%[a-zA-Z_0-9-]+]] = sext i32 [[LD2]] to i64 293*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTLD2]], [[ZEXTLD1_1]] 294*9880d681SAndroid Build Coastguard Worker; We do not combine this one: see 2.b. 295*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXTA:%[a-zA-Z_0-9-]+]] = zext i8 %a to i32 296*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXTZEXTA:%[a-zA-Z_0-9-]+]] = sext i32 [[ZEXTA]] to i64 297*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RESZA:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTZEXTA]], [[ZEXTLD1_3]] 298*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXTB:%[a-zA-Z_0-9-]+]] = sext i32 %b to i64 299*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RESB:%[a-zA-Z_0-9-]+]] = add nsw i64 [[SEXTB]], [[ZEXTLD1_2]] 300*9880d681SAndroid Build Coastguard Worker; 301*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADD:%[a-zA-Z_0-9-]+]] = add nsw i32 302*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RES:%[a-zA-Z_0-9-]+]] = sext i32 [[ADD]] to i64 303*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADDZA:%[a-zA-Z_0-9-]+]] = add nsw i32 304*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RESZA:%[a-zA-Z_0-9-]+]] = sext i32 [[ADDZA]] to i64 305*9880d681SAndroid Build Coastguard Worker; DISABLE: [[ADDB:%[a-zA-Z_0-9-]+]] = add nsw i32 306*9880d681SAndroid Build Coastguard Worker; DISABLE: [[RESB:%[a-zA-Z_0-9-]+]] = sext i32 [[ADDB]] to i64 307*9880d681SAndroid Build Coastguard Worker; 308*9880d681SAndroid Build Coastguard Worker; OPTALL: call void @dummy(i64 [[RES]], i64 [[RESZA]], i64 [[RESB]]) 309*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 310*9880d681SAndroid Build Coastguard Workerdefine void @severalPromotions(i8* %addr1, i32* %addr2, i8 %a, i32 %b) { 311*9880d681SAndroid Build Coastguard Worker %ld = load i8, i8* %addr1 312*9880d681SAndroid Build Coastguard Worker %zextld = zext i8 %ld to i32 313*9880d681SAndroid Build Coastguard Worker %ld2 = load i32, i32* %addr2 314*9880d681SAndroid Build Coastguard Worker %add = add nsw i32 %ld2, %zextld 315*9880d681SAndroid Build Coastguard Worker %sextadd = sext i32 %add to i64 316*9880d681SAndroid Build Coastguard Worker %zexta = zext i8 %a to i32 317*9880d681SAndroid Build Coastguard Worker %addza = add nsw i32 %zexta, %zextld 318*9880d681SAndroid Build Coastguard Worker %sextaddza = sext i32 %addza to i64 319*9880d681SAndroid Build Coastguard Worker %addb = add nsw i32 %b, %zextld 320*9880d681SAndroid Build Coastguard Worker %sextaddb = sext i32 %addb to i64 321*9880d681SAndroid Build Coastguard Worker call void @dummy(i64 %sextadd, i64 %sextaddza, i64 %sextaddb) 322*9880d681SAndroid Build Coastguard Worker ret void 323*9880d681SAndroid Build Coastguard Worker} 324*9880d681SAndroid Build Coastguard Worker 325*9880d681SAndroid Build Coastguard Workerdeclare void @dummy(i64, i64, i64) 326*9880d681SAndroid Build Coastguard Worker 327*9880d681SAndroid Build Coastguard Worker; Make sure we do not try to promote vector types since the type promotion 328*9880d681SAndroid Build Coastguard Worker; helper does not support them for now. 329*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @vectorPromotion 330*9880d681SAndroid Build Coastguard Worker; OPTALL: [[SHL:%[a-zA-Z_0-9-]+]] = shl nuw nsw <2 x i32> zeroinitializer, <i32 8, i32 8> 331*9880d681SAndroid Build Coastguard Worker; OPTALL: [[ZEXT:%[a-zA-Z_0-9-]+]] = zext <2 x i32> [[SHL]] to <2 x i64> 332*9880d681SAndroid Build Coastguard Worker; OPTALL: ret 333*9880d681SAndroid Build Coastguard Workerdefine void @vectorPromotion() { 334*9880d681SAndroid Build Coastguard Workerentry: 335*9880d681SAndroid Build Coastguard Worker %a = shl nuw nsw <2 x i32> zeroinitializer, <i32 8, i32 8> 336*9880d681SAndroid Build Coastguard Worker %b = zext <2 x i32> %a to <2 x i64> 337*9880d681SAndroid Build Coastguard Worker ret void 338*9880d681SAndroid Build Coastguard Worker} 339*9880d681SAndroid Build Coastguard Worker 340*9880d681SAndroid Build Coastguard Worker@a = common global i32 0, align 4 341*9880d681SAndroid Build Coastguard Worker@c = common global [2 x i32] zeroinitializer, align 4 342*9880d681SAndroid Build Coastguard Worker 343*9880d681SAndroid Build Coastguard Worker; PR21978. 344*9880d681SAndroid Build Coastguard Worker; Make sure we support promotion of operands that produces a Value as opposed 345*9880d681SAndroid Build Coastguard Worker; to an instruction. 346*9880d681SAndroid Build Coastguard Worker; This used to cause a crash. 347*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promotionOfArgEndsUpInValue 348*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i16, i16* %addr 349*9880d681SAndroid Build Coastguard Worker 350*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[SEXT:%[a-zA-Z_0-9-]+]] = sext i16 [[LD]] to i32 351*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = add nuw nsw i32 [[SEXT]], zext (i1 icmp ne (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @c, i64 0, i64 1), i32* @a) to i32) 352*9880d681SAndroid Build Coastguard Worker; 353*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[ADD:%[a-zA-Z_0-9-]+]] = add nuw nsw i16 [[LD]], zext (i1 icmp ne (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @c, i64 0, i64 1), i32* @a) to i16) 354*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[RES:%[a-zA-Z_0-9-]+]] = sext i16 [[ADD]] to i32 355*9880d681SAndroid Build Coastguard Worker; 356*9880d681SAndroid Build Coastguard Worker; OPTALL-NEXT: ret i32 [[RES]] 357*9880d681SAndroid Build Coastguard Workerdefine i32 @promotionOfArgEndsUpInValue(i16* %addr) { 358*9880d681SAndroid Build Coastguard Workerentry: 359*9880d681SAndroid Build Coastguard Worker %val = load i16, i16* %addr 360*9880d681SAndroid Build Coastguard Worker %add = add nuw nsw i16 %val, zext (i1 icmp ne (i32* getelementptr inbounds ([2 x i32], [2 x i32]* @c, i64 0, i64 1), i32* @a) to i16) 361*9880d681SAndroid Build Coastguard Worker %conv3 = sext i16 %add to i32 362*9880d681SAndroid Build Coastguard Worker ret i32 %conv3 363*9880d681SAndroid Build Coastguard Worker} 364*9880d681SAndroid Build Coastguard Worker 365*9880d681SAndroid Build Coastguard Worker; Check that we see that one zext can be derived from the other for free. 366*9880d681SAndroid Build Coastguard Worker; OPTALL-LABEL: @promoteTwoArgZextWithSourceExtendedTwice 367*9880d681SAndroid Build Coastguard Worker; OPTALL: [[LD:%[a-zA-Z_0-9-]+]] = load i8, i8* %p 368*9880d681SAndroid Build Coastguard Worker 369*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXT64:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i64 370*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[ZEXT32:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32 371*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES32:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT32]], %b 372*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: [[RES64:%[a-zA-Z_0-9-]+]] = add nuw i64 [[ZEXT64]], 12 373*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: store i32 [[RES32]], i32* %addr 374*9880d681SAndroid Build Coastguard Worker; OPT-NEXT: store i64 [[RES64]], i64* %q 375*9880d681SAndroid Build Coastguard Worker; 376*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[ZEXT32:%[a-zA-Z_0-9-]+]] = zext i8 [[LD]] to i32 377*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[RES32:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT32]], %b 378*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[RES2_32:%[a-zA-Z_0-9-]+]] = add nuw i32 [[ZEXT32]], 12 379*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: store i32 [[RES32]], i32* %addr 380*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: [[ZEXT64:%[a-zA-Z_0-9-]+]] = zext i32 [[RES2_32]] to i64 381*9880d681SAndroid Build Coastguard Worker; DISABLE-NEXT: store i64 [[ZEXT64]], i64* %q 382*9880d681SAndroid Build Coastguard Worker; 383*9880d681SAndroid Build Coastguard Worker; OPTALL-NEXT: ret void 384*9880d681SAndroid Build Coastguard Workerdefine void @promoteTwoArgZextWithSourceExtendedTwice(i8* %p, i64* %q, i32 %b, i32* %addr) { 385*9880d681SAndroid Build Coastguard Workerentry: 386*9880d681SAndroid Build Coastguard Worker %t = load i8, i8* %p 387*9880d681SAndroid Build Coastguard Worker %zextt = zext i8 %t to i32 388*9880d681SAndroid Build Coastguard Worker %add = add nuw i32 %zextt, %b 389*9880d681SAndroid Build Coastguard Worker %add2 = add nuw i32 %zextt, 12 390*9880d681SAndroid Build Coastguard Worker store i32 %add, i32 *%addr 391*9880d681SAndroid Build Coastguard Worker %s = zext i32 %add2 to i64 392*9880d681SAndroid Build Coastguard Worker store i64 %s, i64* %q 393*9880d681SAndroid Build Coastguard Worker ret void 394*9880d681SAndroid Build Coastguard Worker} 395