826 lines · plain
1; Test high-word operations, using "h" constraints to force a high2; register and "r" constraints to force a low register.3;4; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z196 \5; RUN: -no-integrated-as | FileCheck %s6 7; Test loads and stores involving mixtures of high and low registers.8define void @f1(ptr %ptr1, ptr %ptr2) {9; CHECK-LABEL: f1:10; CHECK-DAG: lfh [[REG1:%r[0-5]]], 0(%r2)11; CHECK-DAG: l [[REG2:%r[0-5]]], 0(%r3)12; CHECK-DAG: lfh [[REG3:%r[0-5]]], 4096(%r2)13; CHECK-DAG: ly [[REG4:%r[0-5]]], 524284(%r3)14; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]]15; CHECK-DAG: stfh [[REG1]], 0(%r2)16; CHECK-DAG: st [[REG2]], 0(%r3)17; CHECK-DAG: stfh [[REG3]], 4096(%r2)18; CHECK-DAG: sty [[REG4]], 524284(%r3)19; CHECK: br %r1420 %ptr3 = getelementptr i32, ptr %ptr1, i64 102421 %ptr4 = getelementptr i32, ptr %ptr2, i64 13107122 %old1 = load i32, ptr %ptr123 %old2 = load i32, ptr %ptr224 %old3 = load i32, ptr %ptr325 %old4 = load i32, ptr %ptr426 %res = call { i32, i32, i32, i32 } asm "blah $0, $1, $2, $3",27 "=h,=r,=h,=r,0,1,2,3"(i32 %old1, i32 %old2, i32 %old3, i32 %old4)28 %new1 = extractvalue { i32, i32, i32, i32 } %res, 029 %new2 = extractvalue { i32, i32, i32, i32 } %res, 130 %new3 = extractvalue { i32, i32, i32, i32 } %res, 231 %new4 = extractvalue { i32, i32, i32, i32 } %res, 332 store i32 %new1, ptr %ptr133 store i32 %new2, ptr %ptr234 store i32 %new3, ptr %ptr335 store i32 %new4, ptr %ptr436 ret void37}38 39; Test moves involving mixtures of high and low registers.40define i32 @f2(i32 %old) {41; CHECK-LABEL: f2:42; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 0, 159, 3243; CHECK-DAG: lr %r3, %r244; CHECK: stepa [[REG1]], %r2, %r345; CHECK: risbhg {{%r[0-5]}}, [[REG1]], 0, 159, 046; CHECK: stepb [[REG2:%r[0-5]]]47; CHECK: risblg %r2, [[REG2]], 0, 159, 3248; CHECK: br %r1449 %tmp = call i32 asm "stepa $1, $2, $3",50 "=h,0,{r2},{r3}"(i32 %old, i32 %old, i32 %old)51 %new = call i32 asm "stepb $1, $2", "=&h,0,h"(i32 %tmp, i32 %tmp)52 ret i32 %new53}54 55; Test sign-extending 8-bit loads into mixtures of high and low registers.56define void @f3(ptr %ptr1, ptr %ptr2) {57; CHECK-LABEL: f3:58; CHECK-DAG: lbh [[REG1:%r[0-5]]], 0(%r2)59; CHECK-DAG: lb [[REG2:%r[0-5]]], 0(%r3)60; CHECK-DAG: lbh [[REG3:%r[0-5]]], 4096(%r2)61; CHECK-DAG: lb [[REG4:%r[0-5]]], 524287(%r3)62; CHECK: blah [[REG1]], [[REG2]]63; CHECK: br %r1464 %ptr3 = getelementptr i8, ptr %ptr1, i64 409665 %ptr4 = getelementptr i8, ptr %ptr2, i64 52428766 %val1 = load i8, ptr %ptr167 %val2 = load i8, ptr %ptr268 %val3 = load i8, ptr %ptr369 %val4 = load i8, ptr %ptr470 %ext1 = sext i8 %val1 to i3271 %ext2 = sext i8 %val2 to i3272 %ext3 = sext i8 %val3 to i3273 %ext4 = sext i8 %val4 to i3274 call void asm sideeffect "blah $0, $1, $2, $3",75 "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)76 ret void77}78 79; Test sign-extending 16-bit loads into mixtures of high and low registers.80define void @f4(ptr %ptr1, ptr %ptr2) {81; CHECK-LABEL: f4:82; CHECK-DAG: lhh [[REG1:%r[0-5]]], 0(%r2)83; CHECK-DAG: lh [[REG2:%r[0-5]]], 0(%r3)84; CHECK-DAG: lhh [[REG3:%r[0-5]]], 4096(%r2)85; CHECK-DAG: lhy [[REG4:%r[0-5]]], 524286(%r3)86; CHECK: blah [[REG1]], [[REG2]]87; CHECK: br %r1488 %ptr3 = getelementptr i16, ptr %ptr1, i64 204889 %ptr4 = getelementptr i16, ptr %ptr2, i64 26214390 %val1 = load i16, ptr %ptr191 %val2 = load i16, ptr %ptr292 %val3 = load i16, ptr %ptr393 %val4 = load i16, ptr %ptr494 %ext1 = sext i16 %val1 to i3295 %ext2 = sext i16 %val2 to i3296 %ext3 = sext i16 %val3 to i3297 %ext4 = sext i16 %val4 to i3298 call void asm sideeffect "blah $0, $1, $2, $3",99 "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)100 ret void101}102 103; Test zero-extending 8-bit loads into mixtures of high and low registers.104define void @f5(ptr %ptr1, ptr %ptr2) {105; CHECK-LABEL: f5:106; CHECK-DAG: llch [[REG1:%r[0-5]]], 0(%r2)107; CHECK-DAG: llc [[REG2:%r[0-5]]], 0(%r3)108; CHECK-DAG: llch [[REG3:%r[0-5]]], 4096(%r2)109; CHECK-DAG: llc [[REG4:%r[0-5]]], 524287(%r3)110; CHECK: blah [[REG1]], [[REG2]]111; CHECK: br %r14112 %ptr3 = getelementptr i8, ptr %ptr1, i64 4096113 %ptr4 = getelementptr i8, ptr %ptr2, i64 524287114 %val1 = load i8, ptr %ptr1115 %val2 = load i8, ptr %ptr2116 %val3 = load i8, ptr %ptr3117 %val4 = load i8, ptr %ptr4118 %ext1 = zext i8 %val1 to i32119 %ext2 = zext i8 %val2 to i32120 %ext3 = zext i8 %val3 to i32121 %ext4 = zext i8 %val4 to i32122 call void asm sideeffect "blah $0, $1, $2, $3",123 "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)124 ret void125}126 127; Test zero-extending 16-bit loads into mixtures of high and low registers.128define void @f6(ptr %ptr1, ptr %ptr2) {129; CHECK-LABEL: f6:130; CHECK-DAG: llhh [[REG1:%r[0-5]]], 0(%r2)131; CHECK-DAG: llh [[REG2:%r[0-5]]], 0(%r3)132; CHECK-DAG: llhh [[REG3:%r[0-5]]], 4096(%r2)133; CHECK-DAG: llh [[REG4:%r[0-5]]], 524286(%r3)134; CHECK: blah [[REG1]], [[REG2]]135; CHECK: br %r14136 %ptr3 = getelementptr i16, ptr %ptr1, i64 2048137 %ptr4 = getelementptr i16, ptr %ptr2, i64 262143138 %val1 = load i16, ptr %ptr1139 %val2 = load i16, ptr %ptr2140 %val3 = load i16, ptr %ptr3141 %val4 = load i16, ptr %ptr4142 %ext1 = zext i16 %val1 to i32143 %ext2 = zext i16 %val2 to i32144 %ext3 = zext i16 %val3 to i32145 %ext4 = zext i16 %val4 to i32146 call void asm sideeffect "blah $0, $1, $2, $3",147 "h,r,h,r"(i32 %ext1, i32 %ext2, i32 %ext3, i32 %ext4)148 ret void149}150 151; Test truncating stores of high and low registers into 8-bit memory.152define void @f7(ptr %ptr1, ptr %ptr2) {153; CHECK-LABEL: f7:154; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]]155; CHECK-DAG: stch [[REG1]], 0(%r2)156; CHECK-DAG: stc [[REG2]], 0(%r3)157; CHECK-DAG: stch [[REG1]], 4096(%r2)158; CHECK-DAG: stcy [[REG2]], 524287(%r3)159; CHECK: br %r14160 %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"()161 %res1 = extractvalue { i32, i32 } %res, 0162 %res2 = extractvalue { i32, i32 } %res, 1163 %trunc1 = trunc i32 %res1 to i8164 %trunc2 = trunc i32 %res2 to i8165 %ptr3 = getelementptr i8, ptr %ptr1, i64 4096166 %ptr4 = getelementptr i8, ptr %ptr2, i64 524287167 store i8 %trunc1, ptr %ptr1168 store i8 %trunc2, ptr %ptr2169 store i8 %trunc1, ptr %ptr3170 store i8 %trunc2, ptr %ptr4171 ret void172}173 174; Test truncating stores of high and low registers into 16-bit memory.175define void @f8(ptr %ptr1, ptr %ptr2) {176; CHECK-LABEL: f8:177; CHECK: blah [[REG1:%r[0-5]]], [[REG2:%r[0-5]]]178; CHECK-DAG: sthh [[REG1]], 0(%r2)179; CHECK-DAG: sth [[REG2]], 0(%r3)180; CHECK-DAG: sthh [[REG1]], 4096(%r2)181; CHECK-DAG: sthy [[REG2]], 524286(%r3)182; CHECK: br %r14183 %res = call { i32, i32 } asm "blah $0, $1", "=h,=r"()184 %res1 = extractvalue { i32, i32 } %res, 0185 %res2 = extractvalue { i32, i32 } %res, 1186 %trunc1 = trunc i32 %res1 to i16187 %trunc2 = trunc i32 %res2 to i16188 %ptr3 = getelementptr i16, ptr %ptr1, i64 2048189 %ptr4 = getelementptr i16, ptr %ptr2, i64 262143190 store i16 %trunc1, ptr %ptr1191 store i16 %trunc2, ptr %ptr2192 store i16 %trunc1, ptr %ptr3193 store i16 %trunc2, ptr %ptr4194 ret void195}196 197; Test zero extensions from 8 bits between mixtures of high and low registers.198define i32 @f9(i8 %val1, i8 %val2) {199; CHECK-LABEL: f9:200; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 24, 159, 32201; CHECK-DAG: llcr [[REG2:%r[0-5]]], %r3202; CHECK: stepa [[REG1]], [[REG2]]203; CHECK: risbhg [[REG3:%r[0-5]]], [[REG1]], 24, 159, 0204; CHECK: stepb [[REG3]]205; CHECK: risblg %r2, [[REG3]], 24, 159, 32206; CHECK: br %r14207 %ext1 = zext i8 %val1 to i32208 %ext2 = zext i8 %val2 to i32209 %val3 = call i8 asm sideeffect "stepa $0, $1", "=h,0,r"(i32 %ext1, i32 %ext2)210 %ext3 = zext i8 %val3 to i32211 %val4 = call i8 asm sideeffect "stepb $0", "=h,0"(i32 %ext3)212 %ext4 = zext i8 %val4 to i32213 ret i32 %ext4214}215 216; Test zero extensions from 16 bits between mixtures of high and low registers.217define i32 @f10(i16 %val1, i16 %val2) {218; CHECK-LABEL: f10:219; CHECK-DAG: risbhg [[REG1:%r[0-5]]], %r2, 16, 159, 32220; CHECK-DAG: llhr [[REG2:%r[0-5]]], %r3221; CHECK: stepa [[REG1]], [[REG2]]222; CHECK: risbhg [[REG3:%r[0-5]]], [[REG1]], 16, 159, 0223; CHECK: stepb [[REG3]]224; CHECK: risblg %r2, [[REG3]], 16, 159, 32225; CHECK: br %r14226 %ext1 = zext i16 %val1 to i32227 %ext2 = zext i16 %val2 to i32228 %val3 = call i16 asm sideeffect "stepa $0, $1", "=h,0,r"(i32 %ext1, i32 %ext2)229 %ext3 = zext i16 %val3 to i32230 %val4 = call i16 asm sideeffect "stepb $0", "=h,0"(i32 %ext3)231 %ext4 = zext i16 %val4 to i32232 ret i32 %ext4233}234 235; Test loads of 16-bit constants into mixtures of high and low registers.236define void @f11() {237; CHECK-LABEL: f11:238; CHECK-DAG: iihf [[REG1:%r[0-5]]], 4294934529239; CHECK-DAG: lhi [[REG2:%r[0-5]]], -32768240; CHECK-DAG: llihl [[REG3:%r[0-5]]], 32766241; CHECK-DAG: lhi [[REG4:%r[0-5]]], 32767242; CHECK: blah [[REG1]], [[REG2]], [[REG3]], [[REG4]]243; CHECK: br %r14244 call void asm sideeffect "blah $0, $1, $2, $3",245 "h,r,h,r"(i32 -32767, i32 -32768,246 i32 32766, i32 32767)247 ret void248}249 250; Test loads of unsigned constants into mixtures of high and low registers.251; For stepc, we expect the h and r operands to be paired by the register252; allocator. It doesn't really matter which comes first: LLILL/IIHF would253; be just as good.254define void @f12() {255; CHECK-LABEL: f12:256; CHECK-DAG: llihl [[REG1:%r[0-5]]], 32768257; CHECK-DAG: llihl [[REG2:%r[0-5]]], 65535258; CHECK-DAG: llihh [[REG3:%r[0-5]]], 1259; CHECK-DAG: llihh [[REG4:%r[0-5]]], 65535260; CHECK: stepa [[REG1]], [[REG2]], [[REG3]], [[REG4]]261; CHECK-DAG: llill [[REG1:%r[0-5]]], 32769262; CHECK-DAG: llill [[REG2:%r[0-5]]], 65534263; CHECK-DAG: llilh [[REG3:%r[0-5]]], 2264; CHECK-DAG: llilh [[REG4:%r[0-5]]], 65534265; CHECK: stepb [[REG1]], [[REG2]], [[REG3]], [[REG4]]266; CHECK-DAG: llihl [[REG1:%r[0-5]]], 32770267; CHECK-DAG: iilf [[REG1]], 65533268; CHECK-DAG: llihh [[REG2:%r[0-5]]], 4269; CHECK-DAG: iilf [[REG2]], 524288270; CHECK: stepc [[REG1]], [[REG1]], [[REG2]], [[REG2]]271; CHECK-DAG: iihf [[REG1:%r[0-5]]], 3294967296272; CHECK-DAG: iilf [[REG2:%r[0-5]]], 4294567296273; CHECK-DAG: iihf [[REG3:%r[0-5]]], 1000000000274; CHECK-DAG: iilf [[REG4:%r[0-5]]], 400000275; CHECK: stepd [[REG1]], [[REG2]], [[REG3]], [[REG4]]276; CHECK: br %r14277 call void asm sideeffect "stepa $0, $1, $2, $3",278 "h,h,h,h"(i32 32768, i32 65535,279 i32 65536, i32 -65536)280 call void asm sideeffect "stepb $0, $1, $2, $3",281 "r,r,r,r"(i32 32769, i32 65534,282 i32 131072, i32 -131072)283 call void asm sideeffect "stepc $0, $1, $2, $3",284 "h,r,h,r"(i32 32770, i32 65533,285 i32 262144, i32 524288)286 call void asm sideeffect "stepd $0, $1, $2, $3",287 "h,r,h,r"(i32 -1000000000, i32 -400000,288 i32 1000000000, i32 400000)289 ret void290}291 292; Test selects involving high registers.293; Note that we prefer to use a LOCR and move the result to a high register.294define void @f13(i32 %x, i32 %y) {295; CHECK-LABEL: f13:296; CHECK-DAG: chi %r2, 0297; CHECK-DAG: iilf [[REG1:%r[0-5]]], 2102030405298; CHECK-DAG: lhi [[REG2:%r[0-5]]], 0299; CHECK: locre [[REG1]], [[REG2]]300; CHECK: risbhg [[REG:%r[0-5]]], [[REG1]], 0, 159, 32301; CHECK: blah [[REG]]302; CHECK: br %r14303 %cmp = icmp eq i32 %x, 0304 %val = select i1 %cmp, i32 0, i32 2102030405305 call void asm sideeffect "blah $0", "h"(i32 %val)306 ret void307}308 309; Test selects involving low registers.310define void @f14(i32 %x, i32 %y) {311; CHECK-LABEL: f14:312; CHECK-DAG: chi %r2, 0313; CHECK-DAG: iilf [[REG:%r[0-5]]], 2102030405314; CHECK-DAG: lhi [[REG1:%r[0-5]]], 0315; CHECK: locre [[REG]], [[REG1]]316; CHECK: blah [[REG]]317; CHECK: br %r14318 %cmp = icmp eq i32 %x, 0319 %val = select i1 %cmp, i32 0, i32 2102030405320 call void asm sideeffect "blah $0", "r"(i32 %val)321 ret void322}323 324; Test immediate insertion involving high registers.325define void @f15() {326; CHECK-LABEL: f15:327; CHECK: stepa [[REG:%r[0-5]]]328; CHECK: iihh [[REG]], 4660329; CHECK: stepb [[REG]]330; CHECK: iihl [[REG]], 34661331; CHECK: stepc [[REG]]332; CHECK: br %r14333 %res1 = call i32 asm "stepa $0", "=h"()334 %and1 = and i32 %res1, 65535335 %or1 = or i32 %and1, 305397760336 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1)337 %and2 = and i32 %res2, -65536338 %or2 = or i32 %and2, 34661339 call void asm sideeffect "stepc $0", "h"(i32 %or2)340 ret void341}342 343; Test immediate insertion involving low registers.344define void @f16() {345; CHECK-LABEL: f16:346; CHECK: stepa [[REG:%r[0-5]]]347; CHECK: iilh [[REG]], 4660348; CHECK: stepb [[REG]]349; CHECK: iill [[REG]], 34661350; CHECK: stepc [[REG]]351; CHECK: br %r14352 %res1 = call i32 asm "stepa $0", "=r"()353 %and1 = and i32 %res1, 65535354 %or1 = or i32 %and1, 305397760355 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1)356 %and2 = and i32 %res2, -65536357 %or2 = or i32 %and2, 34661358 call void asm sideeffect "stepc $0", "r"(i32 %or2)359 ret void360}361 362; Test immediate OR involving high registers.363define void @f17() {364; CHECK-LABEL: f17:365; CHECK: stepa [[REG:%r[0-5]]]366; CHECK: oihh [[REG]], 4660367; CHECK: stepb [[REG]]368; CHECK: oihl [[REG]], 34661369; CHECK: stepc [[REG]]370; CHECK: oihf [[REG]], 12345678371; CHECK: stepd [[REG]]372; CHECK: br %r14373 %res1 = call i32 asm "stepa $0", "=h"()374 %or1 = or i32 %res1, 305397760375 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %or1)376 %or2 = or i32 %res2, 34661377 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %or2)378 %or3 = or i32 %res3, 12345678379 call void asm sideeffect "stepd $0", "h"(i32 %or3)380 ret void381}382 383; Test immediate OR involving low registers.384define void @f18() {385; CHECK-LABEL: f18:386; CHECK: stepa [[REG:%r[0-5]]]387; CHECK: oilh [[REG]], 4660388; CHECK: stepb [[REG]]389; CHECK: oill [[REG]], 34661390; CHECK: stepc [[REG]]391; CHECK: oilf [[REG]], 12345678392; CHECK: stepd [[REG]]393; CHECK: br %r14394 %res1 = call i32 asm "stepa $0", "=r"()395 %or1 = or i32 %res1, 305397760396 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %or1)397 %or2 = or i32 %res2, 34661398 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %or2)399 %or3 = or i32 %res3, 12345678400 call void asm sideeffect "stepd $0", "r"(i32 %or3)401 ret void402}403 404; Test immediate XOR involving high registers.405define void @f19() {406; CHECK-LABEL: f19:407; CHECK: stepa [[REG:%r[0-5]]]408; CHECK: xihf [[REG]], 305397760409; CHECK: stepb [[REG]]410; CHECK: xihf [[REG]], 34661411; CHECK: stepc [[REG]]412; CHECK: xihf [[REG]], 12345678413; CHECK: stepd [[REG]]414; CHECK: br %r14415 %res1 = call i32 asm "stepa $0", "=h"()416 %xor1 = xor i32 %res1, 305397760417 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %xor1)418 %xor2 = xor i32 %res2, 34661419 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %xor2)420 %xor3 = xor i32 %res3, 12345678421 call void asm sideeffect "stepd $0", "h"(i32 %xor3)422 ret void423}424 425; Test immediate XOR involving low registers.426define void @f20() {427; CHECK-LABEL: f20:428; CHECK: stepa [[REG:%r[0-5]]]429; CHECK: xilf [[REG]], 305397760430; CHECK: stepb [[REG]]431; CHECK: xilf [[REG]], 34661432; CHECK: stepc [[REG]]433; CHECK: xilf [[REG]], 12345678434; CHECK: stepd [[REG]]435; CHECK: br %r14436 %res1 = call i32 asm "stepa $0", "=r"()437 %xor1 = xor i32 %res1, 305397760438 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %xor1)439 %xor2 = xor i32 %res2, 34661440 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %xor2)441 %xor3 = xor i32 %res3, 12345678442 call void asm sideeffect "stepd $0", "r"(i32 %xor3)443 ret void444}445 446; Test two-operand immediate AND involving high registers.447define void @f21() {448; CHECK-LABEL: f21:449; CHECK: stepa [[REG:%r[0-5]]]450; CHECK: nihh [[REG]], 4096451; CHECK: stepb [[REG]]452; CHECK: nihl [[REG]], 57536453; CHECK: stepc [[REG]]454; CHECK: nihf [[REG]], 12345678455; CHECK: stepd [[REG]]456; CHECK: br %r14457 %res1 = call i32 asm "stepa $0", "=h"()458 %and1 = and i32 %res1, 268500991459 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %and1)460 %and2 = and i32 %res2, -8000461 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %and2)462 %and3 = and i32 %res3, 12345678463 call void asm sideeffect "stepd $0", "h"(i32 %and3)464 ret void465}466 467; Test two-operand immediate AND involving low registers.468define void @f22() {469; CHECK-LABEL: f22:470; CHECK: stepa [[REG:%r[0-5]]]471; CHECK: nilh [[REG]], 4096472; CHECK: stepb [[REG]]473; CHECK: nill [[REG]], 57536474; CHECK: stepc [[REG]]475; CHECK: nilf [[REG]], 12345678476; CHECK: stepd [[REG]]477; CHECK: br %r14478 %res1 = call i32 asm "stepa $0", "=r"()479 %and1 = and i32 %res1, 268500991480 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %and1)481 %and2 = and i32 %res2, -8000482 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %and2)483 %and3 = and i32 %res3, 12345678484 call void asm sideeffect "stepd $0", "r"(i32 %and3)485 ret void486}487 488; Test three-operand immediate AND involving mixtures of low and high registers.489define i32 @f23(i32 %old) {490; CHECK-LABEL: f23:491; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 0492; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 32493; CHECK: stepa %r2, [[REG1]], [[REG2]]494; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 0495; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 32496; CHECK: stepb [[REG2]], [[REG3]], %r2497; CHECK: br %r14498 %and1 = and i32 %old, 14499 %and2 = and i32 %old, 254500 %res1 = call i32 asm "stepa $1, $2, $3",501 "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2)502 %and3 = and i32 %res1, 127503 %and4 = and i32 %res1, 128504 %res2 = call i32 asm "stepb $1, $2, $3",505 "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)506 ret i32 %res2507}508 509; Test RISB[LH]G insertions involving mixtures of high and low registers.510define i32 @f24(i32 %old) {511; CHECK-LABEL: f24:512; CHECK-DAG: risblg [[REG1:%r[0-5]]], %r2, 28, 158, 1513; CHECK-DAG: risbhg [[REG2:%r[0-5]]], %r2, 24, 158, 29514; CHECK: stepa %r2, [[REG1]], [[REG2]]515; CHECK-DAG: risbhg [[REG3:%r[0-5]]], [[REG2]], 25, 159, 62516; CHECK-DAG: risblg %r2, [[REG2]], 24, 152, 37517; CHECK: stepb [[REG2]], [[REG3]], %r2518; CHECK: br %r14519 %shift1 = shl i32 %old, 1520 %and1 = and i32 %shift1, 14521 %shift2 = lshr i32 %old, 3522 %and2 = and i32 %shift2, 254523 %res1 = call i32 asm "stepa $1, $2, $3",524 "=h,r,r,0"(i32 %old, i32 %and1, i32 %and2)525 %shift3 = lshr i32 %res1, 2526 %and3 = and i32 %shift3, 127527 %shift4 = shl i32 %res1, 5528 %and4 = and i32 %shift4, 128529 %res2 = call i32 asm "stepb $1, $2, $3",530 "=r,h,h,0"(i32 %res1, i32 %and3, i32 %and4)531 ret i32 %res2532}533 534; Test TMxx involving mixtures of high and low registers.535define i32 @f25(i32 %old) {536; CHECK-LABEL: f25:537; CHECK-DAG: tmll %r2, 1538; CHECK-DAG: tmlh %r2, 1539; CHECK: stepa [[REG1:%r[0-5]]],540; CHECK-DAG: tmhl [[REG1]], 1541; CHECK-DAG: tmhh [[REG1]], 1542; CHECK: stepb %r2,543; CHECK: br %r14544 %and1 = and i32 %old, 1545 %and2 = and i32 %old, 65536546 %cmp1 = icmp eq i32 %and1, 0547 %cmp2 = icmp eq i32 %and2, 0548 %sel1 = select i1 %cmp1, i32 100, i32 200549 %sel2 = select i1 %cmp2, i32 100, i32 200550 %res1 = call i32 asm "stepa $0, $1, $2",551 "=h,r,r"(i32 %sel1, i32 %sel2)552 %and3 = and i32 %res1, 1553 %and4 = and i32 %res1, 65536554 %cmp3 = icmp eq i32 %and3, 0555 %cmp4 = icmp eq i32 %and4, 0556 %sel3 = select i1 %cmp3, i32 100, i32 200557 %sel4 = select i1 %cmp4, i32 100, i32 200558 %res2 = call i32 asm "stepb $0, $1, $2",559 "=r,h,h"(i32 %sel3, i32 %sel4)560 ret i32 %res2561}562 563; Test two-operand halfword immediate addition involving high registers.564define void @f26() {565; CHECK-LABEL: f26:566; CHECK: stepa [[REG:%r[0-5]]]567; CHECK: aih [[REG]], -32768568; CHECK: stepb [[REG]]569; CHECK: aih [[REG]], 1570; CHECK: stepc [[REG]]571; CHECK: aih [[REG]], 32767572; CHECK: stepd [[REG]]573; CHECK: br %r14574 %res1 = call i32 asm "stepa $0", "=h"()575 %add1 = add i32 %res1, -32768576 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1)577 %add2 = add i32 %res2, 1578 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2)579 %add3 = add i32 %res3, 32767580 call void asm sideeffect "stepd $0", "h"(i32 %add3)581 ret void582}583 584; Test two-operand halfword immediate addition involving low registers.585define void @f27() {586; CHECK-LABEL: f27:587; CHECK: stepa [[REG:%r[0-5]]]588; CHECK: ahi [[REG]], -32768589; CHECK: stepb [[REG]]590; CHECK: ahi [[REG]], 1591; CHECK: stepc [[REG]]592; CHECK: ahi [[REG]], 32767593; CHECK: stepd [[REG]]594; CHECK: br %r14595 %res1 = call i32 asm "stepa $0", "=r"()596 %add1 = add i32 %res1, -32768597 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1)598 %add2 = add i32 %res2, 1599 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2)600 %add3 = add i32 %res3, 32767601 call void asm sideeffect "stepd $0", "r"(i32 %add3)602 ret void603}604 605; Test three-operand halfword immediate addition involving mixtures of low606; and high registers. AHIK/RISBHG would be OK too, instead of RISBHG/AIH.607define i32 @f28(i32 %old) {608; CHECK-LABEL: f28:609; CHECK: ahik [[REG1:%r[0-5]]], %r2, 14610; CHECK: stepa %r2, [[REG1]]611; CHECK: risbhg [[REG1]], [[REG1]], 0, 159, 32612; CHECK: aih [[REG1]], 254613; CHECK: stepb [[REG1]], [[REG2]]614; CHECK: risbhg [[REG3:%r[0-5]]], [[REG2]], 0, 159, 0615; CHECK: aih [[REG3]], 127616; CHECK: stepc [[REG2]], [[REG3]]617; CHECK: risblg %r2, [[REG3]], 0, 159, 32618; CHECK: ahi %r2, 128619; CHECK: stepd [[REG3]], %r2620; CHECK: br %r14621 %add1 = add i32 %old, 14622 %res1 = call i32 asm "stepa $1, $2",623 "=r,r,0"(i32 %old, i32 %add1)624 %add2 = add i32 %res1, 254625 %res2 = call i32 asm "stepb $1, $2",626 "=h,r,0"(i32 %res1, i32 %add2)627 %add3 = add i32 %res2, 127628 %res3 = call i32 asm "stepc $1, $2",629 "=h,h,0"(i32 %res2, i32 %add3)630 %add4 = add i32 %res3, 128631 %res4 = call i32 asm "stepd $1, $2",632 "=r,h,0"(i32 %res3, i32 %add4)633 ret i32 %res4634}635 636; Test large immediate addition involving high registers.637define void @f29() {638; CHECK-LABEL: f29:639; CHECK: stepa [[REG:%r[0-5]]]640; CHECK: aih [[REG]], -32769641; CHECK: stepb [[REG]]642; CHECK: aih [[REG]], 32768643; CHECK: stepc [[REG]]644; CHECK: aih [[REG]], 1000000000645; CHECK: stepd [[REG]]646; CHECK: br %r14647 %res1 = call i32 asm "stepa $0", "=h"()648 %add1 = add i32 %res1, -32769649 %res2 = call i32 asm "stepb $0, $1", "=h,h"(i32 %add1)650 %add2 = add i32 %res2, 32768651 %res3 = call i32 asm "stepc $0, $1", "=h,h"(i32 %add2)652 %add3 = add i32 %res3, 1000000000653 call void asm sideeffect "stepd $0", "h"(i32 %add3)654 ret void655}656 657; Test large immediate addition involving low registers.658define void @f30() {659; CHECK-LABEL: f30:660; CHECK: stepa [[REG:%r[0-5]]]661; CHECK: afi [[REG]], -32769662; CHECK: stepb [[REG]]663; CHECK: afi [[REG]], 32768664; CHECK: stepc [[REG]]665; CHECK: afi [[REG]], 1000000000666; CHECK: stepd [[REG]]667; CHECK: br %r14668 %res1 = call i32 asm "stepa $0", "=r"()669 %add1 = add i32 %res1, -32769670 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %add1)671 %add2 = add i32 %res2, 32768672 %res3 = call i32 asm "stepc $0, $1", "=r,r"(i32 %add2)673 %add3 = add i32 %res3, 1000000000674 call void asm sideeffect "stepd $0", "r"(i32 %add3)675 ret void676}677 678; Test large immediate comparison involving high registers.679define i32 @f31() {680; CHECK-LABEL: f31:681; CHECK: stepa [[REG1:%r[0-5]]]682; CHECK: cih [[REG1]], 1000000000683; CHECK: stepb [[REG2:%r[0-5]]]684; CHECK: clih [[REG2]], 1000000000685; CHECK: br %r14686 %res1 = call i32 asm "stepa $0", "=h"()687 %cmp1 = icmp sle i32 %res1, 1000000000688 %sel1 = select i1 %cmp1, i32 0, i32 1689 %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1)690 %cmp2 = icmp ule i32 %res2, 1000000000691 %sel2 = select i1 %cmp2, i32 0, i32 1692 ret i32 %sel2693}694 695; Test large immediate comparison involving low registers.696define i32 @f32() {697; CHECK-LABEL: f32:698; CHECK: stepa [[REG1:%r[0-5]]]699; CHECK: cfi [[REG1]], 1000000000700; CHECK: stepb [[REG2:%r[0-5]]]701; CHECK: clfi [[REG2]], 1000000000702; CHECK: br %r14703 %res1 = call i32 asm "stepa $0", "=r"()704 %cmp1 = icmp sle i32 %res1, 1000000000705 %sel1 = select i1 %cmp1, i32 0, i32 1706 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1)707 %cmp2 = icmp ule i32 %res2, 1000000000708 %sel2 = select i1 %cmp2, i32 0, i32 1709 ret i32 %sel2710}711 712; Test memory comparison involving high registers.713define void @f33(ptr %ptr1, ptr %ptr2) {714; CHECK-LABEL: f33:715; CHECK: stepa [[REG1:%r[0-5]]]716; CHECK: chf [[REG1]], 0(%r2)717; CHECK: stepb [[REG2:%r[0-5]]]718; CHECK: clhf [[REG2]], 0(%r3)719; CHECK: br %r14720 %res1 = call i32 asm "stepa $0", "=h"()721 %load1 = load i32, ptr %ptr1722 %cmp1 = icmp sle i32 %res1, %load1723 %sel1 = select i1 %cmp1, i32 0, i32 1724 %res2 = call i32 asm "stepb $0, $1", "=h,r"(i32 %sel1)725 %load2 = load i32, ptr %ptr2726 %cmp2 = icmp ule i32 %res2, %load2727 %sel2 = select i1 %cmp2, i32 0, i32 1728 store i32 %sel2, ptr %ptr1729 ret void730}731 732; Test memory comparison involving low registers.733define void @f34(ptr %ptr1, ptr %ptr2) {734; CHECK-LABEL: f34:735; CHECK: stepa [[REG1:%r[0-5]]]736; CHECK: c [[REG1]], 0(%r2)737; CHECK: stepb [[REG2:%r[0-5]]]738; CHECK: cl [[REG2]], 0(%r3)739; CHECK: br %r14740 %res1 = call i32 asm "stepa $0", "=r"()741 %load1 = load i32, ptr %ptr1742 %cmp1 = icmp sle i32 %res1, %load1743 %sel1 = select i1 %cmp1, i32 0, i32 1744 %res2 = call i32 asm "stepb $0, $1", "=r,r"(i32 %sel1)745 %load2 = load i32, ptr %ptr2746 %cmp2 = icmp ule i32 %res2, %load2747 %sel2 = select i1 %cmp2, i32 0, i32 1748 store i32 %sel2, ptr %ptr1749 ret void750}751 752; Test immediate addition with overflow involving high registers.753define void @f35() {754; CHECK-LABEL: f35:755; CHECK: stepa [[REG:%r[0-5]]]756; CHECK: aih [[REG]], -32768757; CHECK: ipm [[REGCC:%r[0-5]]]758; CHECK: afi [[REGCC]], 1342177280759; CHECK: srl [[REGCC]], 31760; CHECK: stepb [[REG]], [[REGCC]]761; CHECK: aih [[REG]], 1762; CHECK: ipm [[REGCC:%r[0-5]]]763; CHECK: afi [[REGCC]], 1342177280764; CHECK: srl [[REGCC]], 31765; CHECK: stepc [[REG]], [[REGCC]]766; CHECK: aih [[REG]], 32767767; CHECK: ipm [[REGCC:%r[0-5]]]768; CHECK: afi [[REGCC]], 1342177280769; CHECK: srl [[REGCC]], 31770; CHECK: stepd [[REG]], [[REGCC]]771; CHECK: br %r14772 %res1 = call i32 asm "stepa $0", "=h"()773 %t1 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res1, i32 -32768)774 %val1 = extractvalue {i32, i1} %t1, 0775 %obit1 = extractvalue {i32, i1} %t1, 1776 %res2 = call i32 asm "stepb $0, $2", "=h,h,d"(i32 %val1, i1 %obit1)777 %t2 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res2, i32 1)778 %val2 = extractvalue {i32, i1} %t2, 0779 %obit2 = extractvalue {i32, i1} %t2, 1780 %res3 = call i32 asm "stepc $0, $2", "=h,h,d"(i32 %val2, i1 %obit2)781 %t3 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res3, i32 32767)782 %val3 = extractvalue {i32, i1} %t3, 0783 %obit3 = extractvalue {i32, i1} %t3, 1784 call void asm sideeffect "stepd $0, $1", "h,d"(i32 %val3, i1 %obit3)785 ret void786}787 788; Test large immediate addition with overflow involving high registers.789define void @f36() {790; CHECK-LABEL: f36:791; CHECK: stepa [[REG:%r[0-5]]]792; CHECK: aih [[REG]], -2147483648793; CHECK: ipm [[REGCC:%r[0-5]]]794; CHECK: afi [[REGCC]], 1342177280795; CHECK: srl [[REGCC]], 31796; CHECK: stepb [[REG]], [[REGCC]]797; CHECK: aih [[REG]], 1798; CHECK: ipm [[REGCC:%r[0-5]]]799; CHECK: afi [[REGCC]], 1342177280800; CHECK: srl [[REGCC]], 31801; CHECK: stepc [[REG]], [[REGCC]]802; CHECK: aih [[REG]], 2147483647803; CHECK: ipm [[REGCC:%r[0-5]]]804; CHECK: afi [[REGCC]], 1342177280805; CHECK: srl [[REGCC]], 31806; CHECK: stepd [[REG]], [[REGCC]]807; CHECK: br %r14808 %res1 = call i32 asm "stepa $0", "=h"()809 %t1 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res1, i32 -2147483648)810 %val1 = extractvalue {i32, i1} %t1, 0811 %obit1 = extractvalue {i32, i1} %t1, 1812 %res2 = call i32 asm "stepb $0, $2", "=h,h,d"(i32 %val1, i1 %obit1)813 %t2 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res2, i32 1)814 %val2 = extractvalue {i32, i1} %t2, 0815 %obit2 = extractvalue {i32, i1} %t2, 1816 %res3 = call i32 asm "stepc $0, $2", "=h,h,d"(i32 %val2, i1 %obit2)817 %t3 = call {i32, i1} @llvm.sadd.with.overflow.i32(i32 %res3, i32 2147483647)818 %val3 = extractvalue {i32, i1} %t3, 0819 %obit3 = extractvalue {i32, i1} %t3, 1820 call void asm sideeffect "stepd $0, $1", "h,d"(i32 %val3, i1 %obit3)821 ret void822}823 824declare {i32, i1} @llvm.sadd.with.overflow.i32(i32, i32) nounwind readnone825 826